文章类型: 原创阅读时长: 4小时
文章地址:
依赖注入(DI,Dependency Inject)与控制反转(IoC,Invertion of Contorl)在许多框架中都存在,如spring、.net、nest等。很多小伙伴都听说过,却不是很了解。
解释
控制反转(IoC),是一种设计原则(设计思想)。用于对象与对象之间的解耦。在传统编程中,对象通常会自行创建和管理其依赖对象,导致组件之间的耦合度高。实现依赖注入的方式就是通过控制反转,将创建对象和依赖关系过程交给外部容器。
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">class</span><<span class="hljs-regexp">/span> <span class="hljs-title class_">A</</span>span>
{
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-title function_"</span>></span>constructor<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>(<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-params"</span>></span>B<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>){
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-comment"</span>></span>// 因为A掌控B的创建,因此A控制了B<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-variable language_"</span>></span>this<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>.<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-property"</span>>b<<span class="hljs-regexp">/span> = <span class="hljs-keyword">new</</span>span> <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-title function_"</span>></span>B<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>();
}
}
依赖注入(Dependency Inject,DI),也叫注入,是一种设计模式(具体实现)。将对象的创建和依赖关系管理由外部容器负责,而不是在具体使用到对象的地方管理。
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">class</span><<span class="hljs-regexp">/span> <span class="hljs-title class_">A</</span>span>
{
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-comment"</span>></span>// B由外部注入,称之为依赖注入<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-title function_"</span>></span>constructor<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>(<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-params"</span>></span>B<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>)
{
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-comment"</span>></span>// B由外部创建,脱离了A的控制,称之为控制反转<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-variable language_"</span>></span>this<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>.<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-property"</span>>b</span> = B;
}
}
为什么需要依赖注入和控制反转
解耦
相信大家都听说过一个法则:“高内聚,低耦合”,第一张图,B 依赖了 A,而 C 通过依赖 B 依赖了 A,稍微多一点这种关系,就会很复杂,难以维护。如果 我们把 B 和 C 所依赖的功能向 A 内聚,那么 B 和 C 就实现了解耦。
还有一种方式是做抽象的接口,只要遵循一定的规则,你就可以把具体的实现使用到这个接口上,这也是解耦。比如内存卡,使用内存卡的设备只是一个接口,而内存卡就是这个接口的具体实现,所以你就可以把不同的内存卡(遵循标准生产的)使用到这个设备上。
IoC 容器
在项目里,通常会遇到两个关于对象的问题,一个是对象数量多,如何统一管理对象的创建和销毁,依赖一个问题是对象间的依赖错综复杂,如何管理他们的依赖关系?
针对上述问题,解决方案就是 IoC 容器,IoC 容器是一个对象管理器,它统一管理对象的创建过程、生命周期、依赖关系,以及提供自动注入,根据配置创建对象的功能。
开源IoC容器Autofac:
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">using</span></span> Autofac;
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">namespace</span></<span class="hljs-title">span</span>> <<span class="hljs-title">span</span> <span class="hljs-title">class</span>=<span class="hljs-string">"hljs-title"</span>>AutofacDemo</span>
{
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">class</span></<span class="hljs-title">span</span>> <<span class="hljs-title">span</span> <span class="hljs-title">class</span>="<span class="hljs-title">hljs</span>-<span class="hljs-title">title</span>"><span class="hljs-title">A</span></<span class="hljs-title">span</span>>
{ }
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">class</span></<span class="hljs-title">span</span>> <<span class="hljs-title">span</span> <span class="hljs-title">class</span>="<span class="hljs-title">hljs</span>-<span class="hljs-title">title</span>"><span class="hljs-title">B</span></<span class="hljs-title">span</span>>
{
A _a;
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-comment"</span>><span class="hljs-comment">// 只需要声明需要注入的对象,由容器自动完成依赖对象的创建与注入</span></span>
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-function"</span>><span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">public</span></span> <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-title"</span>>B</span>(<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-params"</span>>A a</span>)</span>
{
_a = a;
}
}
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">internal</span></span> <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">class</span></<span class="hljs-title">span</span>> <<span class="hljs-title">span</span> <span class="hljs-title">class</span>="<span class="hljs-title">hljs</span>-<span class="hljs-title">title</span>"><span class="hljs-title">Program</span></<span class="hljs-title">span</span>>
{
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-function"</span>><span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">static</span></span> <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">void</span></span> <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-title"</span>>Main</span>(<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-params"</span>><span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-built_in"</span>><span class="hljs-built_in">string</span></span>[] <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">args</span></span></span>)</span>
{
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-comment"</span>><span class="hljs-comment">// 将类型注册至容器中</span></span>
ContainerBuilder builder = <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">new</span></span> ContainerBuilder();
builder.RegisterType&lt;A&gt;();
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-comment"</span>><span class="hljs-comment">// 设置对象的生命周期(单例模式)</span></span>
builder.RegisterType&lt;B&gt;().SingleInstance();
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-comment"</span>><span class="hljs-comment">// 构造IoC容器</span></span>
IContainer container = builder.Build();
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-comment"</span>><span class="hljs-comment">// 从容器中获取对象</span></span>
B b = container.Resolve&lt;B&gt;();
}
}
}
Tags
Recomends
Comments
登录
暂无评论,快来抢沙发吧!