.Net Core AutoFac 使用方法讲解大全,具体详细使用知识总结
-
AutoFac 具体使用知识总结
-
阅读前提示 AutoFac 只是众多IOC框架的其中一种, 比较主流的有
Unity
、autofac
、spring.net
、MEF
、Injection
、Asp.Net Core
的ServiceCollection
,等一些,还有一些,可能自己实现这一套东西。
1.为什么使用AutoFac? (自己的理解综合所链接的因素)
- 传说是速度最快的一个,轻量级性能高
- C#语言联系很紧密,许多框架如Abp都会有默认支持AutoFac,微软的Orchad开源程序使用的就是Autofac
- 支持很多的注入方式,除了传统的 构造函数注入,DI容器注入(使用
IServiceProvider
接口的对象) 如方法注入,属性注入,控制器注入 这些特殊的方式
2.缺点 - 传说没有微软自带的 依赖注入 速度快
AutoFac 几种依赖注入使用方法介绍
-
演示绝大部分都是在 Startup.cs 里面进行的,也有一个测试的控制器
TestController
,重在理解,以下是自己研究的项目源码GitHub地址:-
https://github.com/goodluckily/WebApi-AutoFac
-
结构图片
-
-
最基本的注入方式 通过DL容器的方式 一般的容器注入 初始
-
IServiceCollection serviceDescriptors = new ServiceCollection(); //指定关系 serviceDescriptors.AddScoped
(); //build ServiceProvider serviceProvider = serviceDescriptors.BuildServiceProvider(); //下面是作用域的关系比较 //1.同一个作用域 获取的实例 时同一个 //var testA = (ITestAService)serviceProvider.GetService (); //var testA1 = (ITestAService)serviceProvider.GetService (); //var isEq = object.ReferenceEquals(testA, testA1); //2.再次Build时 范围声明周期 已经发生了变化 //ServiceProvider serviceProvider1 = serviceDescriptors.BuildServiceProvider(); //var testA2 = (ITestAService)serviceProvider1.GetService (); //var isEq1 = object.ReferenceEquals(testA1, testA2); //testA.show();
-
-
AutoFac容器最简单的使用
-
//容器构建着 ContainerBuilder containerBuilder = new ContainerBuilder(); //指定关系 containerBuilder.RegisterType
().As (); //构建 IContainer container = containerBuilder.Build(); //获取服务 ITestAService testA3 = container.Resolve (); testA3.show();
-
-
AutoFac容器 默认支持构造函数注入
-
ContainerBuilder containerBuilder1 = new ContainerBuilder(); containerBuilder1.RegisterType
().As (); containerBuilder1.RegisterType ().As (); IContainer container1 = containerBuilder1.Build(); ITestBService testB = container1.Resolve (); testB.show();
-
-
AutoFac容器 属性注入 PropertiesAutowired()
-
ContainerBuilder containerBuilder2 = new ContainerBuilder(); containerBuilder2.RegisterType
().As (); containerBuilder2.RegisterType ().As (); //支持属性注入的方法 containerBuilder2.RegisterType ().As ().PropertiesAutowired(); IContainer container2 = containerBuilder2.Build(); ITestCService testC = container2.Resolve (); testC.show();
-
-
AutoFac 支持的方法注入
-
ContainerBuilder containerBuilder3 = new ContainerBuilder(); containerBuilder3.RegisterType
().As (); containerBuilder3.RegisterType ().As (); //支持属性注入的方法 containerBuilder3.RegisterType ().As ().PropertiesAutowired(); //方法注入 //其中的SetSevice()方法是在 TestDService里面定义的一个方法 containerBuilder3.RegisterType ().OnActivated(a => a.Instance.SetSevice(a.Context.Resolve ())).As (); //使用 IContainer container3 = containerBuilder3.Build(); ITestDService testD = container3.Resolve (); testD.show();
-
-
AutoFac 声明周期 瞬时(每次获取对象都是一个全新的实例) 示例
-
ContainerBuilder containerBuilder4 = new ContainerBuilder(); containerBuilder4.RegisterType
().As ().InstancePerRequest(); //InstancePerDependency 瞬时 //InstancePerLifetimeScope() 范围 // InstancePerMatchingLifetimeScope("name名称") *匹配 name* 声明周期范围实例 //SingleInstance 单例 //InstancePerRequest 每一个请求,一个实例 IContainer container4 = containerBuilder4.Build(); ITestAService testA4 = container4.Resolve (); ITestAService testA5 = container4.Resolve (); //比较 var IsEq = object.ReferenceEquals(testA4, testA5); Console.WriteLine(IsEq); -
AutoFac 特殊的控制器中使用 属性注入方式
-
需要使用两个特性来实现
-
CustomPropertyAttribute 特性用来 当作标识,且声明只能是属性才能使用该特性
-
CustomPropertySelector 特性是需要给控制器告知哪些属性是可以注入的 (需要一个判断的维度)
-
具体代码详见 GitHub 示例
-
-
整个项目 使用AutoFac 自动构建 关系
-
方式一 使用 配置文件 (完全断开对 实体的依赖)
- 安装 支持的Nuget包
- Autofac.Extensions.DependencyInjection
- Autofac.Configuration
- 内部好像也是用来反射
Dll
来实现,感觉配置文件也挺复杂,所以就没有使用这种方案
- 安装 支持的Nuget包
-
方式二 使用用反射来实现 ******
-
1.收钱 需要在ConfigureServices 里面提供 控制器注入的支持
-
//AutoFac 提供控制器支持 //1 替换控制器的替换规则 //1.1 可以指定控制器让 容器来创建 services.Replace(ServiceDescriptor.Transient
()); -
需要实现自定义实现
ConfigureContainer
方法,注意反射注入的方法需要写在这里面,不然没有效果-
代码如下
-
///
/// AutoFac 自己会调用这个方法 进行注册 /// 1.负责注册 各种服务 /// 2.ServiceCollection 注册的,也同样是可以使用的 /// 3.还支持控制器 里面的属性注入 /// /// public void ConfigureContainer(ContainerBuilder builder) { Assembly serviceDLL = Assembly.Load(new AssemblyName("WebApplicationApi")); //1.Service 后缀类的反射 注入 var serviceTypes = serviceDLL.GetTypes().Where(t => t.Name.EndsWith("Service") && !t.GetTypeInfo().IsAbstract); foreach (var serviceType in serviceTypes) { //var asdfasf = serviceType.Name; foreach (var interType in serviceType.GetInterfaces()) { var sname = serviceType.Name; var Iname = interType.Name; Console.WriteLine($"{sname}--->{Iname}"); builder.RegisterType(serviceType).As(interType).InstancePerDependency() .AsImplementedInterfaces()//自动以其实现的所有接口类型暴露(包括IDisposable接口) .InstancePerLifetimeScope() .PropertiesAutowired();//支持属性注入的方法; } } //2 首先需要在Service,里面提供支持 services.Replace(.......) //2.1 控制器实例的注入 var controllerTypes = typeof(Startup).GetTypeInfo().Assembly.DefinedTypes. Where(x => x.IsClass && typeof(ControllerBase).GetTypeInfo().IsAssignableFrom(x)). Select(x => x.AsType()). ToArray(); builder.RegisterTypes(controllerTypes) //支持属性注入的方法; //CustomPropertySelector 设置哪些是可以被注入的 (指定特性属性注入的支持) .PropertiesAutowired(new CustomPropertySelector()); }
-
-
-
这样就能直接在控制里面使用了
- 具体使用如下
- 具体使用如下
-
-