打代碼之前先說一下幾個概念,那就是什么是IOC、DI、DIP
雖然網上講這些的已經有很多了,我這里還是要再贅述一下
IOC容器就是一個工廠,負責創建對象的
IOC控制反轉:只是把上端對下端的依賴,換成第三方容器決定
DI依賴注入:就是在構造某個對象時,能將對象依賴的東西自動的初始化進去
正是因為要實現IOC,所以才誕生了DI的技術手段
DIP就是上層模塊不應該依賴底層模塊,它們都應該依賴於抽象,具體點是Service不應該依賴於Repository,而應該依賴於IRepository
.Net Core中自帶了輕量級的IOC的容器
依次是Transient、Scoped、Singleton
services.AddTransient<>():服務在每次請求時被創建,適合無狀態的服務
services.AddScoped<>():服務每個請求只創建一次
services.Singleton<>():單例,只創建一次,第一次被請求的時候被創建
code部分:
定義一個接口ICacheContext和一個實現類CacheContext
假如我們現在想要使用CacheContext類中的方法,按照我們以前的思路肯定是:
//實例化 CacheContext context=new CacheContext(); //調用方法 context.method();
這就產生了依賴!我們要依賴於抽象不能依賴於具體實現細節,這樣做:
//實例化 ICacheContext context=new CacheContext(); //調用方法 context.method();
接下來用IOC容器實現,將對象交給IOC容器托管。
這樣之后可以使用構造函數、屬性、方法進行注入
這里使用構造函數注入,如下:
接下來使用第三方IOC容器:Autofac
導包:Autofac與Autofac.Extensions.DependencyInjection
在Program中,加入如下代碼:
public class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .UseServiceProviderFactory(new AutofacServiceProviderFactory())//配置UseServiceProviderFactory
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
在Startup中加入一個方法:
public void ConfigureContainer(ContainerBuilder builder) { builder.RegisterType<CacheContext>().As<ICacheContext>(); }
還是一樣在Controller中使用構造函數注入,和上面一樣
但是在真實的項目開發中不可能一個個的寫
我們可以通過反射加載程序集的強名稱,但是api層必須要對其引用
例如我這里api層引用了Icewo.BaseManage.MSSQLDB層
在ConfigureContainer方法中添加如下代碼
var assemblysServicesNoInterfaces = Assembly.Load("Icewo.BaseManage.MSSQLDB"); builder.RegisterAssemblyTypes(assemblysServicesNoInterfaces);
Icewo.BaseManage.MSSQLDB層是沒有實現層的,也就是說他沒有接口層
如果是有接口層的話,方法又不一樣了
例如我這里有Business層和IBusiness層,如果api層直接對Business層進行引用,這就造成程序高度耦合。所以api層只引用IBusiness層 DIP(依賴倒置)
在ConfigureContainer中添加如下方法:
注意:你要拷貝Business.dll到api層的bin目錄下或者改一下輸出路徑,不然啟動的時候會報錯。
var basePath = Microsoft.DotNet.PlatformAbstractions.ApplicationEnvironment.ApplicationBasePath; var businessDllFile = Path.Combine(basePath, "Icewo.BaseManage.Business.dll"); var assemblysBusiness = Assembly.LoadFrom(businessDllFile); builder.RegisterAssemblyTypes(assemblysBusiness) .AsImplementedInterfaces() .InstancePerDependency();
還是一樣在Controllers中以構造函數注入的方式進行調用
水平有限,但是希望能幫到大家。
END