赞
踩
阅读前提示 AutoFac 只是众多IOC框架的其中一种, 比较主流的有Unity
、autofac
、spring.net
、MEF
、Injection
、Asp.Net Core
的ServiceCollection
,等一些,还有一些,可能自己实现这一套东西。
1.为什么使用AutoFac? (自己的理解综合所链接的因素)
IServiceProvider
接口的对象) 如方法注入,属性注入,控制器注入 这些特殊的方式AutoFac 几种依赖注入使用方法介绍
演示绝大部分都是在 Startup.cs 里面进行的,也有一个测试的控制器TestController
,重在理解,以下是自己研究的项目源码GitHub地址:
最基本的注入方式 通过DL容器的方式 一般的容器注入 初始
- IServiceCollection serviceDescriptors = new ServiceCollection();
- //指定关系
- serviceDescriptors.AddScoped<ITestAService, TestAService>();
- //build
- ServiceProvider serviceProvider = serviceDescriptors.BuildServiceProvider();
-
- //下面是作用域的关系比较
-
- //1.同一个作用域 获取的实例 时同一个
- //var testA = (ITestAService)serviceProvider.GetService<ITestAService>();
- //var testA1 = (ITestAService)serviceProvider.GetService<ITestAService>();
- //var isEq = object.ReferenceEquals(testA, testA1);
-
- //2.再次Build时 范围声明周期 已经发生了变化
- //ServiceProvider serviceProvider1 = serviceDescriptors.BuildServiceProvider();
- //var testA2 = (ITestAService)serviceProvider1.GetService<ITestAService>();
-
- //var isEq1 = object.ReferenceEquals(testA1, testA2);
-
- //testA.show();
AutoFac容器最简单的使用
- //容器构建着
- ContainerBuilder containerBuilder = new ContainerBuilder();
- //指定关系
- containerBuilder.RegisterType<TestAService>().As<ITestAService>();
- //构建
- IContainer container = containerBuilder.Build();
- //获取服务
- ITestAService testA3 = container.Resolve<ITestAService>();
- testA3.show();
-
AutoFac容器 默认支持构造函数注入
- ContainerBuilder containerBuilder1 = new ContainerBuilder();
- containerBuilder1.RegisterType<TestAService>().As<ITestAService>();
- containerBuilder1.RegisterType<TestBService>().As<ITestBService>();
- IContainer container1 = containerBuilder1.Build();
- ITestBService testB = container1.Resolve<ITestBService>();
- testB.show();
AutoFac容器 属性注入 PropertiesAutowired()
- ContainerBuilder containerBuilder2 = new ContainerBuilder();
- containerBuilder2.RegisterType<TestAService>().As<ITestAService>();
- containerBuilder2.RegisterType<TestBService>().As<ITestBService>();
- //支持属性注入的方法
- containerBuilder2.RegisterType<TestCService>().As<ITestCService>().PropertiesAutowired();
- IContainer container2 = containerBuilder2.Build();
-
- ITestCService testC = container2.Resolve<ITestCService>();
- testC.show();
-
AutoFac 支持的方法注入
- ContainerBuilder containerBuilder3 = new ContainerBuilder();
- containerBuilder3.RegisterType<TestAService>().As<ITestAService>();
- containerBuilder3.RegisterType<TestBService>().As<ITestBService>();
- //支持属性注入的方法
- containerBuilder3.RegisterType<TestCService>().As<ITestCService>().PropertiesAutowired();
- //方法注入
- //其中的SetSevice()方法是在 TestDService里面定义的一个方法
- containerBuilder3.RegisterType<TestDService>().OnActivated(a => a.Instance.SetSevice(a.Context.Resolve<ITestAService>())).As<ITestDService>();
- //使用
- IContainer container3 = containerBuilder3.Build();
- ITestDService testD = container3.Resolve<ITestDService>();
- testD.show();
AutoFac 声明周期 瞬时(每次获取对象都是一个全新的实例) 示例
- ContainerBuilder containerBuilder4 = new ContainerBuilder();
- containerBuilder4.RegisterType<TestAService>().As<ITestAService>().InstancePerRequest();
-
- //InstancePerDependency 瞬时
- //InstancePerLifetimeScope() 范围
- // InstancePerMatchingLifetimeScope("name名称") *匹配 name* 声明周期范围实例
- //SingleInstance 单例
- //InstancePerRequest 每一个请求,一个实例
-
- IContainer container4 = containerBuilder4.Build();
- ITestAService testA4 = container4.Resolve<ITestAService>();
- ITestAService testA5 = container4.Resolve<ITestAService>();
- //比较
- var IsEq = object.ReferenceEquals(testA4, testA5);
- Console.WriteLine(IsEq);
AutoFac 特殊的控制器中使用 属性注入方式
需要使用两个特性来实现
CustomPropertyAttribute 特性用来 当作标识,且声明只能是属性才能使用该特性
CustomPropertySelector 特性是需要给控制器告知哪些属性是可以注入的 (需要一个判断的维度)
具体代码详见 GitHub 示例
整个项目 使用AutoFac 自动构建 关系
方式一 使用 配置文件 (完全断开对 实体的依赖)
Dll
来实现,感觉配置文件也挺复杂,所以就没有使用这种方案方式二 使用用反射来实现 ******
1.收钱 需要在ConfigureServices 里面提供 控制器注入的支持
- //AutoFac 提供控制器支持
- //1 替换控制器的替换规则
- //1.1 可以指定控制器让 容器来创建
- services.Replace(ServiceDescriptor.Transient<IControllerActivator,ServiceBasedControllerActivator>());
需要实现自定义实现ConfigureContainer
方法,注意反射注入的方法需要写在这里面,不然没有效果
代码如下
- /// <summary>
- /// AutoFac 自己会调用这个方法 进行注册
- /// 1.负责注册 各种服务
- /// 2.ServiceCollection 注册的,也同样是可以使用的
- /// 3.还支持控制器 里面的属性注入
- /// </summary>
- /// <param name="builder"></param>
- 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());
-
- }
这样就能直接在控制里面使用了
以上就是AutoFac的一些基本使用方法,欢迎大家讨论,转载请标明原创地址~ 谢谢~~~Bye~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。