欢迎访问欧博亚洲(Allbet Game)!

首页科技正文

焦作二手房出售:.NET IoC模式依赖反转(DIP)、控制反转(Ioc)、依赖注入(DI)

admin2020-05-125

依赖倒置原则(DIP)

依赖倒置(Dependency Inversion Principle,缩写DIP)是面向工具六大基本原则之一。他是指一种特定的的解耦形式,使得高层次的模块不依赖低层次的模块的实现细节,依赖关系被颠倒(反转),从而使得低层次模块依赖于高层次模块的需求抽象.

该原则划定:

  • 高层次的模块不应该依赖低层次模块,二者都应该依赖其抽象接口.
  • 抽象接口不应该依赖于详细实现,而详细实现则应该依赖于抽象接口.

通过如下一个简朴的示例,我们来看一下,我们通过一个简朴地下单流程向我们的用户发送相关的短信或者邮件.


public SendingEmail
{
    public void Send(string message){
        //do something
    }
}

public Ordering
{
    SendingEmail _sendingEmail=null;
    public void Order(string message){
        //Order business operation
        if(_sendingEmail == null)
        {
            _sendingEmail=new SendingEmail();
        }
        _sendingEmail.Send(message);
    }
}

这样看我们的代码没问题,现在只要我们完成了订单操作那么,那么则会触发发送功效,然则他却违反了DIP,由于Ordering类依赖于SendingEmail类,而SendingEmail类不是抽象类,而是一个详细的类.那我们再来想一个若是这时候营业口的人过来向我们提出了一个新的需求,要求我们改为短信而不是Email,那么我们需要怎么改?

public class SendingSMS
{
    public void Send(string message){
        //do something
    }
}
public Ordering
{
    SendingEmail _sendingEmail=null;
    SendingSMS _sendingSMS=null;
    bool isSendingSMS=true;
    public void Order(string message){
        //Order business operation
        if(isSendingSMS){
            if(_sendingSMS == null)
            {
                _sendingSMS=new SendingSMS();
            }
            _sendingSMS.Send(message);
        }else{
            if(_sendingEmail == null)
            {
                _sendingEmail=new SendingEmail();
            }
            _sendingEmail.Send(message);
        }
       
    }
}

凭据上述需求我们不得不建立更多的类,而且在Ordering类中声明他,最后我们还需要使用IF ELSE语句来决议使用SMS照样使用电子邮件.然则当我们有更多这种处置操作后,那么可能比现在还杂乱,这就意味着我们必须在Ordering类中声明更多新的详细类的实例.

我们需要抽离出来一种方式,让高级模块去依赖于抽象,用它来取代我们实现类,该抽象将映射到实现类.

控制反转(IoC)

控制反转(Inversion of Control,缩写为IOC)是面向工具中的设计原则,他可以辅助我们使高层模块依赖于抽象,而不是底层模块的详细实现.换句话说,他有助于实现(依赖倒置原则——DIP).

public interface ICustomerCommunication
{
    void Send(string message);
}

然后我们修改SendingEmailSendingSMS类以从ICustomerCommunication接口继续.

public class SendingEmail:ICustomerCommunication
{
    public void Send(string message){
        //do something
    }
}

public class SendingSMS:ICustomerCommunication
{
    public void Send(string message){
        //do something
    }
}

我们再来修改一下Ordering类以使用该抽象接口

public Ordering
{
    ICustomerCommunication _customerComm=null;
    bool isSendingSMS=true;
    public void Order(string message){
        //Order business operation
        if(isSendingSMS){
            if(_customerComm == null)
            {
                _customerComm=new SendingSMS();
            }
            _customerComm.Send(message);
        }else{
            if(_customerComm == null)
            {
                _customerComm=new SendingEmail();
            }
            _customerComm.Send(message);
        }
       
    }
}

通过如上修改我们做的控制反转更相符DIP.现在我们的高级模块只需要依赖于抽象,而不用去依赖实现.

依赖注入(DI)

依赖注入(Depeondency Injection,缩写为DI)是实现控制反转的一种方式.常用的依赖注入方式有3种:

  • 组织函数注入
  • 方式注入
  • 属性注入

虽然说通过上面代码我们实现了IoC,而且Ordering类依赖于ICustomerCommunication抽象,但我们仍然在Ordering类中使用了实现类,这使用我们无法在类于类之间完全解耦.

  if(isSendingSMS){
    if(_customerComm == null)
    {
        _customerComm=new SendingSMS();
    }
        _customerComm.Send(message);
    }else{
        if(_customerComm == null)
        {
            _customerComm=new SendingEmail();
        }
        _customerComm.Send(message);
    }

那我们再来说说DI,DI主要辅助我们将实现注入到抽象的类(ICustomerCommunication接口)中.DI的主要削减类之间的耦合,而且将抽象和详细实现的绑定移除依赖类.

  • 组织函数注入
    通过组织函数注入我们将实现类的工具通报给依赖类的组织函数,并将其分配给这个接口.
public class Ordering
{
    ICustomerCommunication _customerComm=null;
    public Ordering(ICustomerCommunication customerComm){
        _customerComm=customerComm;
    }
    public void Order(string message){
        _customerComm.Send(message);
    }
}

在上面的代码中,组织函数将接纳实现类工具绑定到接口中.若是我们将SendingSMS的实现通报给这个类,我们要做的就是声明一个SendingSMS类的实例,然后将其通报给Ordering的组织函数,如下所示:

SendingSMS sendingSMS=new SendingSMS();
Ordering ordering=new Ordering(sendingSMS);
ordering.Order("msg");
  • 方式注入
    通过使用组织函数注入,我们将不得不在Ordering类的生计期内使用实现类的实例SendingSMS或SendingEmail类.现在若是要在每次挪用该方式时通报实现类的实例,则必须使用方式注入.

public class Ordering
{
    public void Order(ICustomerCommunication customerComm,string message){
        _customerComm=customerComm;
        _customerComm.Send(message);
    }
}

挪用方式如下所示

SendingSMS sendingSMS=new SendingSMS();
Ordering ordering=new Ordering(sendingSMS);
ordering.Order(sendingSMS,"msg");
  • 属性注入

通过如上形貌我们知道了组织函数注入方式在整个生命周期中使用依赖类,而方式注入是将我们的注入直接去限于该方式中,然后我们再去领会一下属性注入


public class Ordering
{
    public ICustomerCommunication customerComm {get;set;}
    public void Order(string message){
        _customerComm.Send(message);
    }
}

挪用方式如下所示

SendingSMS sendingSMS=new SendingSMS();
Ordering ordering=new Ordering(sendingSMS);
ordering.customerComm=sendingSMS;
ordering.Order("msg");

实在组织函数注入是实现DI最常用的方式.若是需要在每个方式挪用上通报差别的依赖关系,则可以使用方式注入属性注入的使用照样比较少的.

Reference

https://zh.wikipedia.org/wiki/控制反转

https://zh.wikipedia.org/zh-hans/依赖反转原则

,

Sunbet 申博

Sunbet 申博www.114co.cn立足亚洲,展望国际,在即将到来的2019年,努力在技术、安全、服务上尽善尽美,致力提高业务品质,期望与业界精英共同开拓未来。

转载声明:本站发布文章及版权归原作者所有,转载本站文章请注明文章来源:欧博亚洲(Allbet Game)!

本文链接:http://www.czshenhaifb.com/post/1121.html

网友评论