概要:因为不知道写啥,所以随便找个东西乱说几句,嗯,就这样,就是这个目的。
1.IOC是啥呢?IOC - Inversion of Control,即控制反转的意思,这里要搞明白的就是,它是一种思想,一种用于设计的方式(手段),(并不是前几天园子中刚出的一片说是原则),OO原则不包含它,再说下,他不是原则!!
那么,既然是控制反转,怎么反转的?对吧,说到重点了吧。很简单,通过一个容器,将对象注册到这个容器之后,由这个容器来创建对象,从而免去了手动创建对象以及创建后对象(资源)的获取。
你可能又会问,有什么好处?我直接new不也一样的吗?对的,你说的很对,但是这样做必然导致了对象之间的耦合度增加了,既不方便测试,又不方便复用;IOC却很好的解决了这些问题,可以i很容易创建出一个松耦合的应用框架,同时更方便于测试。
常用的 IOC工具有 Autofac,castle windsor,unit,structMap等,本人使用过的只有 autofac,unit,还有自带的mef,,,也能算一个吧,还有现在的core的 DependencyInJection。
2.Core中的DI是啥?
依赖注入的有三种方式:属性,构造函数,接口注入;
在core之前,我们在.net framework中使用 autofac的时候,这三种方式我们可以随意使用的,比较方便(因为重点不是在这,所以不说core之前),但是有一点是,在web api和 web中属性注入稍微有点不同,自行扩展吧。
core中我们使用DI(dependency injection)的时候,属性注入好像还不支持,所以跳过这个,我们使用更多的是通过自定义接口使用构造函数注入。下面会有演示。
演示前我们先弄清楚 core中的这个 dependencyInJection到底是个啥,他是有啥构成的。这是git上提供的源码:https://github.com/aspnet/DependencyInjection,但是,,那么一大陀东西你肯定不想看,想走捷径吧,所以这里简要说一下,看图:
当我们创建了一个core 的项目之后,我们,会看到 startUp.cs的ConfigureServices使用了一个IServiceCollection的参数,这个东西,就是我们1中所说的IOC的容器,他的构成如图所示,是由一系列的ServiceDescriptor组成,是一个集合对象,而本质上而言,
ServiceDescriptor也是一个容器,其中定义了对象了类型以及生命周期,说白了控制生命周期的,也是有他决定的(生命周期:Scoped:本次完整请求的生命,Singleton:伴随整个应用程序神一样存在的声明,Transient:瞬时声明,用一下消失)。
另外,我们还会见到另一个东西,IServiceProvider,这个是服务的提供器,IServiceCollection在获取一系列的ServiceDescriptor之后其实他还是并没有创建我们所需要的实现对象的,比如AssemblyFinder实现了IAssemblyFinder的接口,此时我们只是将其加入IserviceCollection,
直接使用IAssemblyFinder获取到的一定是null对象,这里是通过BuildServiceProvider()这个方法,将这二者映射在一起的,此时这个容器才真正的创建完成,这时候我们再使用 IAssemblyFinder的时候便可以正常。这个动作好比是我们自己通过Activator 反射创建某个接口的实现类,
当然其内部也是这个样的实现道理。如果需要更深入见这篇文章:https://www.cnblogs.com/cheesebar/p/7675214.html
好了,扯了这么多理论,说一千道一万不如来一个实战,下面就看怎么用。
3.怎么用?首先我们先快速创建一个项目,并创建ICustomerService接口和CustomerServiceImpl实现类,同时在startup.cs的ConfigureService中注册到services容器:
测试代码:
public interface ICustomerService : IDependency { Task<string> GetCustomerInfo(); } public class CustomerServiceImpl : ICustomerService { public async Task<string> GetCustomerInfo() { return await Task.FromResult("放了一年的牛了"); } } startUp.cs的ConfigureService中注册到容器: public void ConfigureServices(IServiceCollection services) { services.AddTransient<ICustomerService, CustomerServiceImpl>(); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); } //controller中的注入 private readonly ICustomerService _customerService; public ValuesController(ICustomerService customerService) { _customerService = customerService; } // GET api/values [HttpGet] public async Task<ActionResult<IEnumerable<string>>> Get() { return new string[] { await _customerService.GetCustomerInfo()}; }