我是模仿和依赖注入的新手,需要一些指导。
我的应用程序使用典型的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创建内部构造函数。然后我可以使用测试项目中的Accessor来调用构造函数。但仍然有那种气味。
这里有什么常见的解决方案。我一定是做错了。我怎样才能改进架构?
答案 0 :(得分:4)
您可以像这样定义类:
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的依赖注入框架示例:AutoFac,Castle,Spring.NET,StructureMap,Ninject和Managed Extensibility Framework。< / p>
答案 1 :(得分:2)
我answered昨天提出了一个关于如何structure a .NET solution我认为可以解决问题的问题。
在我的回答中,关键点应该是没有任何“实现”程序集引用其他“实现”程序集。这应该可以解决您关注问题的分离。
此外,该结构还几乎要求使用依赖注入,它非常适合单元测试和模拟的使用。
我希望它有所帮助。
答案 2 :(得分:0)
如果你想避免从UI dll引用数据访问dll,那么你可以将数据访问接口/基类提取到第三个库中,并且另外两个引用它。