标签:
在net Core3.1上基于winform实现依赖注入实例目录
1.配景net core3.1是微软LTS恒久3年撑持版本,正式颁布于2019-12-03,并且在windows平台上撑持了Winfrom跟WPF桌面应用。本文介绍了使用Winform时的第一步,将应用层以及ORM涉及到的DBconfig,仓储层等依赖注入到容器中,并通过结构函数法从容器中挪用实例,供应各窗体控件使用。
备注:本文的依赖注入讲解基于微软原生自带的DI,通过Ninject或者AutoFac可自行模仿操纵,道理相通。
依赖注入是通过反转控制(IOC),设计模式属于代办代理模式+工厂模式,由serviceProvider按照实例接口或者实例类型挪用,注入时生命周期的设置,控制实例化及配置实例生命周期,并返回实例给措施员挪用,从而到达解放措施员的出产力,不用再去new 一个个实例,也不用去考虑实例之间的依赖关系,也不用去考虑实例的生命周期。实现,分为三个阶段,第一,措施员将处事注入处事容器阶段,第二措施员DI实例挪用阶段,第三serviceProvider处事打点者按照注入时的配置返回给措施对应的实例以及配置好实例的生命周期。
一张图就可以理解依赖注入实例挪用过程
图片来源来由,感谢感动作者。
这里再向读者做个说明ServiceCollection是处事容器,serviceProvider是处事打点者,打点着处事容器,当措施发送抽象接口,或者类型时,serviceProvider会按照设置好的生命周期,返回需要的实例配置好实例的生命周期给措施员使用。
2.1依赖注入的目的通过代办代理模式serviceProvider控制反转,他将持有控制权,将所有需要用到的接口,类型,反射出对应的实例,实例化以及设置好实例的生命周期,然后将控制权返还给措施员,不用再去new 一个个实例,也不用去考虑实例之间的依赖关系,也不用去考虑实例的生命周期,最终目的就是解放措施员的出产力,让措施员更轻松地写措施。
2.2依赖注入带来的好处 2.2.1生命周期的控制在注入的同时可以设置如下三种生命周期:
Transient
每次注入时,都从头 new 一个新的实例。
Scoped
每个 Request 都从头 new 一个新的实例,同一个 Request 不管颠末几多个 Pipeline 都是用同一个实例。
Singleton
被实例化后就不会消掉,措施运行期间只会有一个实例。
界说同一个例子对应三个差别生命周期的接口
public interface ISample { int Id { get; } } public interface ISampleTransient : ISample { } public interface ISampleScoped : ISample { } public interface ISampleSingleton : ISample { } public class Sample : ISampleTransient, ISampleScoped, ISampleSingleton { private static int _counter; private int _id; public Sample() { _id = ++_counter; } public int Id => _id; }将对应的处事与接口注册到容器中
public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddTransient<ISampleTransient, Sample>(); services.AddScoped<ISampleScoped, Sample>(); services.AddSingleton<ISampleSingleton, Sample>(); // Singleton 也可以用以下要领注册 // services.AddSingleton<ISampleSingleton>(new Sample()); } }Controller中获取对应DI实例的HashCode
public class HomeController : Controller { private readonly ISample _transient; private readonly ISample _scoped; private readonly ISample _singleton; public HomeController( ISampleTransient transient, ISampleScoped scoped, ISampleSingleton singleton) { _transient = transient; _scoped = scoped; _singleton = singleton; } public IActionResult Index() { ViewBag.TransientId = _transient.Id; ViewBag.TransientHashCode = _transient.GetHashCode(); ViewBag.ScopedId = _scoped.Id; ViewBag.ScopedHashCode = _scoped.GetHashCode(); ViewBag.SingletonId = _singleton.Id; ViewBag.SingletonHashCode = _singleton.GetHashCode(); return View(); } }VewBag 显示组件
<table border="1"> <tr><td colspan="3">Cotroller</td></tr> <tr><td>Lifetimes</td><td>Id</td><td>Hash Code</td></tr> <tr><td>Transient</td><td>@ViewBag.TransientId</td><td>@ViewBag.TransientHashCode</td></tr> <tr><td>Scoped</td><td>@ViewBag.ScopedId</td><td>@ViewBag.ScopedHashCode</td></tr> <tr><td>Singleton</td><td>@ViewBag.SingletonId</td><td>@ViewBag.SingletonHashCode</td></tr> </table>可自行做测试,具体可参考此博客
2.2.2 实现了展现层(挪用者)与处事类之间的解耦