依赖注入
依赖注入
-
控制反转(ioc)
控制反转是 面向对象编程中的一种(设计原则),可以用来减低计算机代码之间的耦合度,实质上体现的意思是控制权的转移,即原来控制权在A手中,现在需要B来接管,平常需要一个类对象的时候需要new,现在把new一个类对象的工作交给ioc容器,当我们需要一个类对象的时候直接向Ioc容器
-
依赖注入(DI)
-
依赖:当一个类需要另一个类协作来完成工作时就产生了依赖,设计原则:依赖于抽象而不是具体的实现
-
依赖注入是实现Ioc思想的一种方式
-
实现依赖注入主要是有4种方法,(构造器,方法,属性,服务)
-
-
DI的核心组件
IServiceCollection 负责注册IServiceProvider 负责提供实例
-
注入方式
构造器注入
1: public class Foo 2: { 3: public IBar Bar{get; private set;} 4: public Foo(IBar bar) 5: { 6: this.Bar = bar; 7: } 8: }
属性注入
```c# 1: public class Foo 2: { 3: public IBar Bar{get; set;} 4: 5: [Injection] 6: public IBaz Baz {get; set;} 7: } ```
方法注入
1: public class Foo 2: { 3: public IBar Bar{get; private set;} 4: 5: [Injection] 6: public Initialize(IBar bar) 7: { 8: this.Bar = bar; 9: }
直接注入IserviceProvider
services.AddSingleton<ISingletonService,SingletonService>();
然后在构造函数中通过如下方式获取具体实现 public HomeController(IServiceProvider serviceProvider) { var singletonService = serviceProvider.GetService<SingletonService>(); }
通过GetService方式
public HomeController(IServiceProvider serviceProvider) { var singletonService = serviceProvider.GetService<ISingletonService>(); }
集合方式
services.AddSingleton<ISingletonService, SingletonService1>(); services.AddSingleton<ISingletonService, SingletonService2>();
public AuthController(IEnumerable<ISingletonService> eventBuses) { eventBus = eventBuses.FirstOrDefault(h => h.GetType() == typeof(SingletonService2)); }
工厂方式注入
services.AddSingleton(serviceProvider => { Func<Type, IEventBus> func = key => { if (key!=null) { return serviceProvider.GetServices<IEventBus>().FirstOrDefault((c) => c.GetType() == key); } else throw new ArgumentException(""); }; return func; });
private readonly IEventBus eventBus; public AuthController(Func<Type, IEventBus> _eventBus, IAuthService _authService) { authService = _authService; eventBus = _eventBus(typeof(RabbitmqEventBus)); }
框架autofac
//1:类型注入 builder.RegisterType<>().As<>(); //2:实例注入 var output = new StringWriter(); builder.RegisterInstance(output).As<TextWriter>(); //3:对象注入 builder.Register(c => new ConfigReader("mysection")).As<IConfigReader>(); //4:泛型注入 builder.RegisterGeneric(typeof(NHibernateRepository<>)) .As(typeof(IRepository<>)).InstancePerLifetimeScope(); //5:程序集注入 //注册拦截器 builder.RegisterType<ValidatorAop>();;
-
依赖注入生命周期
- AddTransient:(瞬时) 每次请求,获取一个新的实例。即同一个请求获取多次也是不同的实例
- AddScoped:(作用域) 每次请求,都获取一个新的实例,同一个请求获取多次都是同一个实例
适用于:在处理请求的应用,在请求结束之后会释放有作用域的服务
注意点:在中间件使用有作用域的服务时,请将该服务注入到Invoke和InvokeAsync方法(请不要使用构造函数注入,会强制服务的行为变成单例) - AddSingleton:(单例)每次请求获取同一个实例
-