.NET Core中怎么使用Autofac
今天小编给大家分享一下.NETCore中怎么使用Autofac的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。
Autofac 容器Autofac 是一款.NETIoC 容器. 它管理类之间的依赖关系, 从而使应用在规模及复杂性增长的情况下依然可以轻易地修改. 它的实现方式是将常规的.net类当做组件
处理.
安装 NuGet 程序包:Autofac 6.0.0
创建一个 ContainerBuiler
注册接口和实现关系
通过 ContainerBuiler 的 Build 方法,得到 IContainer 容器
通过 IContainer 容器获取实例
使用服务
ITestServiceA
和TestServiceA
publicinterfaceITestServiceA{voidShow();}publicclassTestServiceA:ITestServiceA{publicTestServiceA(){Console.WriteLine($"{this.GetType().Name}被构造了...");}publicvoidShow(){Console.WriteLine($"Thisisa{this.GetType().Name}Instance...");}}
Program 中的Main
方法
varbuilder=newContainerBuilder();builder.RegisterType<TestServiceA>().As<ITestServiceA>();varcontainer=builder.Build();//获取服务实例vartestService=container.Resolve<ITestServiceA>();testService.Show();Autofac 多种注入方式
ITestServiceB
和TestServiceB
publicinterfaceITestServiceB{voidShow();}publicclassTestServiceB:ITestServiceB{privateITestServiceA_testServiceA;publicvoidSetService(ITestServiceAtestServiceA){_testServiceA=testServiceA;}publicTestServiceB(){Console.WriteLine($"{this.GetType().Name}被构造了...");}publicvoidShow(){//_testServiceA.Show();Console.WriteLine($"Thisisa{this.GetType().Name}Instance...");}}
ITestServiceC
和TestServiceC
publicinterfaceITestServiceC{voidShow();}publicclassTestServiceC:ITestServiceC{publicTestServiceC(){Console.WriteLine($"{this.GetType().Name}被构造了...");}publicvoidShow(){Console.WriteLine($"Thisisa{this.GetType().Name}Instance...");}}
ITestServiceD
和TestServiceD
publicinterfaceITestServiceD{voidShow();}publicclassTestServiceD:ITestServiceD{publicITestServiceATestServiceA{get;set;}publicITestServiceBTestServiceB{get;set;}publicITestServiceCTestServiceC{get;set;}publicTestServiceD(){Console.WriteLine($"{this.GetType().Name}被构造了...");}publicvoidShow(){//TestServiceA.Show();//TestServiceB.Show();//TestServiceC.Show();Console.WriteLine($"Thisisa{this.GetType().Name}Instance...");}}
构造函数注入
varbuilder=newContainerBuilder();builder.RegisterType<TestServiceA>().As<ITestServiceA>();builder.RegisterType<TestServiceB>().As<ITestServiceB>();builder.RegisterType<TestServiceC>().As<ITestServiceC>();builder.RegisterType<TestServiceD>().As<ITestServiceD>();varcontainer=builder.Build();//获取服务实例vartestService=container.Resolve<ITestServiceA>();testService.Show();
属性注入
varbuilder=newContainerBuilder();builder.RegisterType<TestServiceA>().As<ITestServiceA>();builder.RegisterType<TestServiceB>().As<ITestServiceB>();builder.RegisterType<TestServiceC>().As<ITestServiceC>();builder.RegisterType<TestServiceD>().As<ITestServiceD>().PropertiesAutowired();varcontainer=builder.Build();//获取服务实例vartestService=container.Resolve<ITestServiceD>();testService.Show();
方法注入
varbuilder=newContainerBuilder();builder.RegisterType<TestServiceA>().As<ITestServiceA>();builder.RegisterType<TestServiceB>().OnActivated(e=>e.Instance.SetService(e.Context.Resolve<ITestServiceA>())).As<ITestServiceB>();builder.RegisterType<TestServiceC>().As<ITestServiceC>();builder.RegisterType<TestServiceD>().As<ITestServiceD>();varcontainer=builder.Build();//获取服务实例vartestService=container.Resolve<ITestServiceB>();testService.Show();Autofac 生命周期
InstancePerDependency:默认模式,每次调用,都会重新实例化对象;每次请求都创建一个新的对象;
varbuilder=newContainerBuilder();builder.RegisterType<TestServiceA>().As<ITestServiceA>().InstancePerDependency();varcontainer=builder.Build();vartestServiceA=container.Resolve<ITestServiceA>();vartestServiceA1=container.Resolve<ITestServiceA>();Console.WriteLine(object.ReferenceEquals(testServiceA,testServiceA1));
SingleInstance:单例模式,每次调用,都会使用同一个实例化的对象;每次都用同一个对象;
varbuilder=newContainerBuilder();builder.RegisterType<TestServiceA>().As<ITestServiceA>().SingleInstance();varcontainer=builder.Build();vartestServiceA=container.Resolve<ITestServiceA>();vartestServiceA1=container.Resolve<ITestServiceA>();Console.WriteLine(object.ReferenceEquals(testServiceA,testServiceA1));
InstancePerLifetimeScope: 同一个生命周期域中,每次调用,都会使用同一个实例化的对象;每次都用同一个对象;且每个不同的生命周期域中的实例是唯一的,不共享的。
varbuilder=newContainerBuilder();builder.RegisterType<TestServiceA>().As<ITestServiceA>().InstancePerLifetimeScope();varcontainer=builder.Build();ITestServiceAtestServiceA15;ITestServiceAtestServiceA16;using(varscope1=container.BeginLifetimeScope()){vartestServiceA11=scope1.Resolve<ITestServiceA>();vartestServiceA12=scope1.Resolve<ITestServiceA>();Console.WriteLine(object.ReferenceEquals(testServiceA11,testServiceA12));testServiceA15=testServiceA12;}using(varscope1=container.BeginLifetimeScope()){vartestServiceA13=scope1.Resolve<ITestServiceA>();vartestServiceA14=scope1.Resolve<ITestServiceA>();Console.WriteLine(object.ReferenceEquals(testServiceA13,testServiceA14));testServiceA16=testServiceA14;}Console.WriteLine(object.ReferenceEquals(testServiceA15,testServiceA16));
InstancePerMatchingLifetimeScope: 同一个匹配的生命周期域中,每次调用,都会使用同一个实例化的对象;每次都用同一个对象;且每个不匹配的生命周期域中的实例是唯一的,不共享的。
varbuilder=newContainerBuilder();builder.RegisterType<TestServiceA>().As<ITestServiceA>().InstancePerMatchingLifetimeScope("Run2948");varcontainer=builder.Build();ITestServiceAtestServiceA15;ITestServiceAtestServiceA16;using(varscope1=container.BeginLifetimeScope("Run2948")){vartestServiceA11=scope1.Resolve<ITestServiceA>();using(varscope2=container.BeginLifetimeScope()){vartestServiceA12=scope2.Resolve<ITestServiceA>();Console.WriteLine(object.ReferenceEquals(testServiceA11,testServiceA12));}testServiceA15=testServiceA11;}using(varscope1=container.BeginLifetimeScope("Run2948")){vartestServiceA13=scope1.Resolve<ITestServiceA>();using(varscope2=container.BeginLifetimeScope()){vartestServiceA14=scope2.Resolve<ITestServiceA>();Console.WriteLine(object.ReferenceEquals(testServiceA13,testServiceA14));}testServiceA16=testServiceA13;}Console.WriteLine(object.ReferenceEquals(testServiceA15,testServiceA16));
InstancePerOwned: 在一个所拥有的实例创建的生命周期中,每次调用,都会使用同一个实例化的对象;每次都用同一个对象;(较少使用)
InstancePerHttpRequest: 同一次Http请求上下文中,每次调用,都会使用同一个实例化的对象;每次都用同一个对象;仅适用于 ASP.NET (CORE) MVC 或 WebForm 应用程序
Autofac 支持配置文件安装 NuGet 程序包:Autofac.Extensions.DependencyInjection 7.1.0
、Autofac.Configuration 6.0.0
新建配置文件(指定接口和实现的对应关系)autofac.json
:
{"components":[{"type:"One.Services.TestServiceA,One","services":[{"type":"One.Services.ITestServiceA,One"}],"instanceScope":"single-instance","injectProperties":true},{"type:"One.Services.TestServiceB,One","services":[{"type":"One.Services.ITestServiceB,One"}],"instanceScope":"single-instance","injectProperties":true},{"type:"One.Services.TestServiceC,One","services":[{"type":"One.Services.ITestServiceC,One"}],"instanceScope":"single-instance","injectProperties":true},{"type:"One.Services.TestServiceD,One","services":[{"type":"One.Services.ITestServiceD,One"}],"instanceScope":"single-instance","injectProperties":true}]}
读取配置文件,完成服务对应关系的注册
varbuilder=newContainerBuilder();varconfig=newConfigurationBuilder();varconfigSource=newJsonConfigurationSource(){Path="Config/autofac.json",Optional=false,ReloadOnChange=true};config.Add(configSource);varconfigModule=newConfigurationModule(config.Build());builder.RegisterModule(configModule);varcontainer=builder.Build();//获取服务实例vartestServiceA=container.Resolve<ITestServiceA>();vartestServiceD=container.Resolve<ITestServiceD>();testServiceD.Show();
新建 ITestServiceA 的新版实现类TestServiceUpdate
publicclassTestServiceUpdate:ITestServiceA{publicTestServiceUpdate(){Console.WriteLine($"{this.GetType().Name}被构造了...");}publicvoidShow(){Console.WriteLine($"Thisisa{this.GetType().Name}Instance...");}}
通过修改配置文件autofac.json
来实现快速实现 ITestServiceA 的实现的重新定义:
{"components":[{"type:"One.Services.TestServiceUpdate,One","services":[{"type":"One.Services.ITestServiceA,One"}],"instanceScope":"single-instance","injectProperties":true},//...Autofac 整合 .NET 5 MVC
安装 NuGet 程序包:Autofac.Extensions.DependencyInjection 7.1.0
Program文件中指定 Autofac 工厂替换默认工厂:
publicstaticIHostBuilderCreateHostBuilder(string[]args)=>Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder=>{webBuilder.UseStartup<Startup>();}).UseServiceProviderFactory(newAutofacServiceProviderFactory());
在 Startup 类中增加 ConfigureContainer 方法:
publicvoidConfigureContainer(ContainerBuilderbuilder){builder.RegisterType<TestServiceA>().As<ITestServiceA>();}
通过控制器构造函数注入,获取实例
[Route("api/[controller]")][ApiController]publicclassValuesController:ControllerBase{privatereadonlyITestServiceA_serviceA;publicValuesController(ITestServiceAserviceA{_serviceA=serviceA;}[HttpGet]publicIActionResultGet(){_serviceA.Show();returnOk();}}
使用 IServiceCollection 注册的服务,将来也会交给 Autofac 管理
publicvoidConfigureServices(IServiceCollectionservices){#regionIServiceCollection注册的服务,将来也会交给Autofac处理services.AddTransient<ITestServiceA,TestServiceA>();services.AddTransient<ITestServiceB,TestServiceB>();services.AddTransient<ITestServiceC,TestServiceC>();#endregion}publicvoidConfigureContainer(ContainerBuilderbuilder){//builder.RegisterType<TestServiceA>().As<ITestServiceA>();//builder.RegisterType<TestServiceB>().As<ITestServiceB>();//builder.RegisterType<TestServiceC>().As<ITestServiceC>();builder.RegisterType<TestServiceD>().As<ITestServiceD>();}Autofac 支持控制器属性注入
控制器本身是一个类,它的实例其实是有 IControllerActivator 来创建的。
指定控制器的实例由容器来创建
publicvoidConfigureServices(IServiceCollectionservices){//...#region指定控制器的实例由容器来创建services.Replace(ServiceDescriptor.Transient<IControllerActivator,ServiceBasedControllerActivator>());#endregion}
注册控制器的抽象和具体的关系
publicvoidConfigureContainer(ContainerBuilderbuilder){builder.RegisterType<TestServiceA>().As<ITestServiceA>().PropertiesAutowired();builder.RegisterType<TestServiceB>().As<ITestServiceB>();#region注册所有控制器的关系及控制器实例化所需要的组件varcontrollersTypesInAssembly=typeof(Startup).Assembly.GetExportedTypes().Where(type=>typeof(ControllerBase).IsAssignableFrom(type)).ToArray();builder.RegisterTypes(controllersTypesInAssembly).PropertiesAutowired();#endregion}
在控制器内定义属性
[Route("api/[controller]")][ApiController]publicclassValuesController:ControllerBase{publicITestServiceATestServiceA{get;set;}publicITestServiceBTestServiceB{get;set;}[HttpGet]publicIActionResultGet(){TestServiceA.Show();TestServiceB.Show();returnOk();}}
扩展:自己控制哪些属性需要做依赖注入(默认是让控制器中的属性都依赖注入)
[AttributeUsage(AttributeTargets.Property,AllowMultiple=false,Inherited=true)]publicclassAutowaredAttribute:Attribute{}publicclassPropertySelector:IPropertySelector{publicboolInjectProperty(PropertyInfopropertyInfo,objectinstance){returnpropertyInfo.CustomAttributes.Any(ca=>ca.AttributeType==typeof(AutowaredAttribute));}}
publicvoidConfigureContainer(ContainerBuilderbuilder){builder.RegisterType<TestServiceA>().As<ITestServiceA>();builder.RegisterType<TestServiceB>().As<ITestServiceB>();#region注册所有控制器的关系及控制器实例化所需要的组件varcontrollersTypesInAssembly=typeof(Startup).Assembly.GetExportedTypes().Where(type=>typeof(ControllerBase).IsAssignableFrom(type)).ToArray();builder.RegisterTypes(controllersTypesInAssembly).PropertiesAutowired(newPropertySelector());#endregion}
[Route("api/[controller]")][ApiController]publicclassValuesController:ControllerBase{[Autowared]publicITestServiceATestServiceA{get;set;}publicITestServiceBTestServiceB{get;set;}[HttpGet]publicIActionResultGet(){TestServiceA.Show();TestServiceB.Show();returnOk();}}Autofac 单实例多实现
publicvoidConfigureContainer(ContainerBuilderbuilder){builder.RegisterType<TestServiceA>().As<ITestServiceA>();builder.RegisterType<TestServiceUpdate>().As<ITestServiceA>();}
如果多个实现同时注册,则后注册的实现就会覆盖先注册的实现,最后将返回最后一个注册的实现。
如果多个实现同时注册,可以通过一个 IEnumerable<实例> 来获取到所有的实现。
privatereadonlyIEnumerable<ITestServiceA>_testServiceAs;publicValuesController(IEnumerable<ITestServiceA>testServiceAs){_testServiceAs=testServiceAs;}
当多个实现同时注册后,可以通过以下方式继续注册 实例 的所有实现。从而可以在控制器中直接使用具体实现类作为实现。
publicvoidConfigureContainer(ContainerBuilderbuilder){builder.RegisterType<TestServiceA>().As<ITestServiceA>();builder.RegisterType<TestServiceUpdate>().As<ITestServiceA>();builder.RegisterSource(newAnyConcreteTypeNotAlreadyRegisteredSource(type=>type.IsAssignableTo<ITestServiceA>()));}
privatereadonlyTestServiceA_testServiceA;privatereadonlyTestServiceUpdate_testServiceUpdate;publicValuesController(TestServiceAtestServiceA,TestServiceUpdatetestServiceUpdate){_testServiceA=testServiceA;_testServiceUpdate=testServiceUpdate;}
扩展:Autofac 的注册逻辑可以通过 Module 来拆分管理。
publicclassAutofacModule:Autofac.Module{protectedoverridevoidLoad(ContainerBuilderbuilder){//base.Load(builder);builder.RegisterType<TestServiceA>().As<ITestServiceA>();builder.RegisterType<TestServiceUpdate>().As<ITestServiceA>();builder.RegisterSource(newAnyConcreteTypeNotAlreadyRegisteredSource(type=>type.IsAssignableTo<ITestServiceA>()));}}
publicvoidConfigureContainer(ContainerBuilderbuilder){//builder.RegisterModule(newAutofacModule());builder.RegisterModule<AutofacModule>();}Autofac 支持 AOP
AOP 面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。Autofac 的AOP是通过 Castle(也是一个容器)项目的名为 Autofac.Extras.DynamicProxy 核心部分实现的,顾名思义其实现方式为动态代理。
安装 NuGet 程序包:Castle.Core 4.4.1
、Autofac.Extras.DynamicProxy 6.0.0
新建自定义 AOP 拦截器
publicclassCustomAutofacAop:IInterceptor{publicvoidIntercept(IInvocationinvocation){{Console.WriteLine("方法执行前...");}invocation.Proceed();{Console.WriteLine("方法执行后...");}}}
在接口上标记需要使用的拦截器
[Intercept(typeof(CustomAutofacAop))]publicinterfaceITestServiceA{voidShow();}
注册自定义拦截器,并允许实例接口使用拦截器
publicvoidConfigureContainer(ContainerBuilderbuilder){//builder.RegisterType<CustomAutofacAop>();builder.RegisterType(typeof(CustomAutofacAop));builder.RegisterType<TestServiceA>().As<ITestServiceA>();builder.RegisterType<TestServiceUpdate>().As<ITestServiceA>().EnableInterfaceInterceptors();}
在控制器中调用实例,即可成功执行 AOP 拦截器
[Route("api/[controller]")][ApiController]publicclassValuesController:ControllerBase{privatereadonlyTestServiceA_testServiceA;privatereadonlyTestServiceUpdate_testServiceUpdate;publicValuesController(TestServiceAtestServiceA,TestServiceUpdatetestServiceUpdate){_testServiceA=testServiceA;_testServiceUpdate=testServiceUpdate;}publicIActionResultGet(){_testServiceA.Show();_testServiceUpdate.Show();returnOk();}}
以上就是“.NETCore中怎么使用Autofac”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注亿速云行业资讯频道。
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。