.Net Core中IOC容器的使用
江北、 人气:1打代码之前先说一下几个概念,那就是什么是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
加载全部内容