Dependency injection Rhino模拟、依赖注入和关注点分离

Dependency injection Rhino模拟、依赖注入和关注点分离,dependency-injection,rhino-mocks,n-tier-architecture,separation-of-concerns,Dependency Injection,Rhino Mocks,N Tier Architecture,Separation Of Concerns,我不熟悉模仿和依赖注入,需要一些指导 我的应用程序使用典型的N层体系结构,其中BLL引用DAL,UI引用BLL而不是DAL。非常直截了当 比如说,我有以下几个类: class MyDataAccess : IMyDataAccess {} class MyBusinessLogic {} 每个都存在于单独的程序集中 我想在MyBusinessLogic的测试中模拟MyDataAccess。因此,我向MyBusinessLogic类添加了一个构造函数,以获取依赖项注入的IMyDataAccess

我不熟悉模仿和依赖注入,需要一些指导

我的应用程序使用典型的N层体系结构,其中BLL引用DAL,UI引用BLL而不是DAL。非常直截了当

比如说,我有以下几个类:

class MyDataAccess : IMyDataAccess {}
class MyBusinessLogic {}
每个都存在于单独的程序集中

我想在MyBusinessLogic的测试中模拟MyDataAccess。因此,我向MyBusinessLogic类添加了一个构造函数,以获取依赖项注入的IMyDataAccess参数。但现在,当我尝试在UI层上创建MyBusinessLogic实例时,它需要对DAL的引用

我想我可以在MyBusinessLogic上定义一个默认构造函数来设置一个默认的IMyDataAccess实现,但这不仅看起来像一个代码味道,实际上并没有解决问题。我仍然有一个签名中带有IMyDataAccess的公共构造函数。因此UI层仍然需要对DAL的引用才能编译

我正在考虑的一个可能的解决方案是使用IMyDataAccess参数为MyBusinessLogic创建一个内部构造函数。然后我可以使用测试项目中的访问器来调用构造函数。但还是有那种味道

这里常见的解决方案是什么。我一定是做错了什么。如何改进体系结构?

昨天我问了一个问题,我认为如何改进体系结构可以解决您的问题

在我的回答中,您需要注意的一点是,没有一个“实现”程序集引用了其他“实现”程序集。这将解决您的关注点分离问题

此外,该结构还几乎强制使用依赖注入,非常适合单元测试和模拟的使用


我希望它能有所帮助。

如果您不想从UI dll引用数据访问dll,那么您可以将数据访问接口/基类提取到第三个库中,并同时引用其他两个库。

您可以这样定义您的类:

public class MainForm : Form
{
    private readonly businessLogic;

    public MainForm(IBusinessLogic businessLogic)
    {
        this.businessLogic = businessLogic;
    }
}

public class BusinessLogic : IBusinessLogic
{
    private IDataLayer dataLayer;

    public BusinessLogic(IDataLayer dataLayer)
    {
        this.dataLayer = dataLayer;
    }
}

public class DataLayer : IDataLayer
{
    public DataLayer(string connectionString)
    {
    }
}
请注意,主窗体如何不知道这里的DAL。现在我们确实需要一段知道所有类的代码,以便将它们连接在一起。这通常在应用程序开始时完成:

public static void Main(string[] args)
{
   var dataLayer = new DataLayer("foo");
   var businessLogic = new BusinessLogic(dataLayer);
   var mainForm = new MainForm(businessLogic);

   Application.Run(mainForm);
}
当然,这是一个简化的例子。如果您在实践中有几十个或数百个类,那么这样的启动连接可能会变得非常大和复杂,特别是当循环依赖开始发挥作用时。这就是为什么依赖注入框架被创建来用XML配置文件、按代码配置或.NET属性替换代码。但基本思想是一样的


.NET、、和的依赖注入框架示例这听起来是一个非常好的解决方案,但我认为要说服我的团队中的其他人重新构建我们的整个应用程序将是一项艰巨的任务。使用IoC容器如何影响性能?我非常喜欢这个解决方案,目前正在使用Castle。@whatispunk:使用IoC容器对启动后的性能没有影响。如果由于连接在一起的对象数量太多,启动时间太长,那么容器中通常有一些工具来启用延迟加载(例如,对于托管扩展性框架,System.lazy),这是有意义的。就我而言,我正在开发一个Web应用程序,所以启动时间并不重要。谢谢你的帮助。