本文是介紹netcore3.x版本的autofac的使用,以下是netcore2.X的
NetCore2.X面向接口編程中,Autofac(依賴注入)的基本使用
項目基本介紹:
備註,項目源代碼在上傳GitHub後會展示鏈接
csdn代碼鏈接
項目用的面向接口編程
(PS:面向接口編程的核心含義就是,層與層之間只通過接口關聯)
EptDemo是API主程序:依賴於IRepo和IServ
EptDemo.IRepo是倉儲接口層,負責提供Repo層的接口
EptDemo.Repo是倉儲層,負責與數據庫進行數據串接,依賴Repo
EptDemo.IServ是服務接口層,一般只提供給主程序,依賴於IRepo
EptDemo.Serv是服務層,作用是完成與Repo層的數據串接,依賴於IRepo和IServe層
Autofac的實現依賴注入
加載Autofac包
管理nugut下載Autofac包並安裝
包如下:
Autofac.Extensions.DependencyInjection
Autofac.Extras.DynamicProxy
註冊
1.Startup類中,添加ConfigureContainer函數,進行註冊。
AutofacModuleRegister是自己寫的一個類,下面會介紹
//此函數名稱是固定寫法,不能變更
public void ConfigureContainer(ContainerBuilder builder)
{
builder.RegisterModule(new AutofacModuleRegister());
}
2.Program類中,更新CreateHostBuilder的配置,在執行創建HostBuilder後,註冊Autofac服務
/// <summary>
/// 在createhostbuilder的地方使用Autofac
/// </summary>
/// <param name="args"></param>
/// <returns></returns>
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
- 新建AutofacModuleRegister類,完成依賴注入操作
public class AutofacModuleRegister : Autofac.Module
{
// private static readonly ILog log = LogManager.GetLogger(typeof(AutofacModuleRegister));
protected override void Load(ContainerBuilder builder)
{
var basePath = AppContext.BaseDirectory;
#region 帶有接口層的服務注入
var servicesDLLFile = Path.Combine(basePath, "EptDemo.Serv.dll");
var repositoryDllFile = Path.Combine(basePath, "EptDemo.Repo.dll");
if (!(File.Exists(servicesDLLFile) && File.Exists(repositoryDllFile)))
{
//1此處一開始可能是因爲解耦的問題,導致運行的時候,dll文件沒有編程
//1.1此時需要F6編譯/工具欄build-build solution/解決方案右鍵編譯
//2還有一個問題是,repo和serv層的數據再編譯的時候,編譯產生的文件不在EptDemo目錄下
//2.1此時可以更改項目repo和serv的dll編譯路徑,項目右鍵-屬性-編譯-輸出路徑輸入--“..\EptDemo\bin\Debug\”
var msg = "Repository.dll和services.dll丟失,因爲項目解耦了,所以需要F6編譯,再F5運行,請檢查bin文件夾,並拷貝";
throw new Exception(msg);
}
//獲取services.dll程序集服務,並註冊
var assemblyServices = Assembly.LoadFrom(servicesDLLFile);
builder.RegisterAssemblyTypes(assemblyServices)
.AsImplementedInterfaces()
.InstancePerDependency()
.EnableInterfaceInterceptors();//引用Autofac.extras.DynamicProxy
//.InterceptedBy();//允許將攔截器服務的列表分配給註冊 涉及到動態代理
//獲取repository.dll程序集服務,並註冊
var assemblyRepository = Assembly.LoadFrom(repositoryDllFile);
builder.RegisterAssemblyTypes(assemblyRepository)
.AsImplementedInterfaces()
.InstancePerDependency();
//.EnableInterfaceInterceptors()
//.InterceptedBy();
#endregion
}
}
重要:
1.因爲本項目通過面向接口編程,所以EptDemo若是沒有通過配置,是一定沒有Ept.Serv和Ept.Repo兩個dll文件的。
方案一:在Ept主項目中添加兩個項目的引用,
方案二(推薦):將其他兩個項目的dll編譯路徑變更到主項目中
右鍵Serv項目-屬性-編譯-輸出路徑-寫入路徑"…\EptDemo\bin\Debug",Ept是主項目的路徑
其實目的就是,將對應項目編譯後的dll放入到主程序下面。
Repo同上操作
2.因爲整個解決方案是經過解耦的,所以基本上在更新代碼後,最好編譯一下整個解決方案。
使用
1.Serv的初始化:在各自的控制器中,初始化私有的IDemoServ變量,並在構造函數中賦值
private readonly IDemoServ _demoServ;
public WeatherForecastController(ILogger<WeatherForecastController> logger,IDemoServ demoServ)
{
_logger = logger;
_demoServ = demoServ;
}
2.Serv的使用
[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
_demoServ.GetDemos();
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
})
.ToArray();
}