我正在开发一个WinForms应用程序,该应用程序已配置为典型的3层UI,BLL和DAL。我创建了一个单独的项目来充当启动项目。还创建了另一个项目,作为自制的依赖注入容器,目的是执行所有依赖注入设置。自制依赖注入容器由启动项目实例化,然后启动项目将实例化对象传递给第一个WinForm。
自制的依赖注入容器实现如下所示:
public class AppDependencyInjection
{
public BLL.DataServices.DepartmentDataServices BllDeptDataServices = null;
private DAL.DataServices.DepartmentDataServices DalDeptDataServices = null;
public BLL.ReportServices.RequestReports BllRequestReports = null;
private DAL.ReportServices.RequestReports DalRequestReports = null;
public AppDependencyInjection()
{
DalDeptDataServices = new DAL.DataServices.DepartmentDataServices();
BllDeptDataServices = new BLL.DataServices.DepartmentDataServices(DalDeptDataServices);//inject actual implementations
DalRequestReports = new DAL.ReportServices.RequestReports();
BllRequestReports = new BLL.ReportServices.RequestReports(DalRequestReports);//inject actual implementations
}
}
启动项目如下所示:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
//instantiate dependent classes and inject into class constructors
AppDependencyInjection aDI = new AppDependencyInjection();
//Pass objects with injected dependencies into app startup WinForm
Application.Run(new MDIS.WinForms.UI.Form1(aDI.BllDeptDataServices, aDI.BllRequestReports));
}
接收的WinForm通过注入的对象实例化如下:
public Form1(BLL.DataServices.DepartmentDataServices aBllDeptDataServices,
BLL.ReportServices.RequestReports aBllRequestReports)
{
InitializeComponent();
BllDeptDataServices = aBllDeptDataServices;
BllRequestReports = aBllRequestReports;
}
WinForm在以下两个按钮单击事件中使用注入的对象:
private void btnGetAllDepartments_Click(object sender, EventArgs e)
{
List<DepartmentDto> aDepartmentDtoList = BllDeptDataServices.GetAllDepartments();
}
private void btnGetAllRequests_Click(object sender, EventArgs e)
{
List<RequestDetailDto> aRequestDetailDtoList = BllRequestReports.GetAllRequestDetail();
}
现在这个问题没什么用,因为我只传入2个注入的对象。但是,如果对象数量增长到5以上,那么这似乎是一个问题,那么我将超过5个参数传递给启动WinForm。如果我决定将名为AppDependencyInjection的自制依赖注入容器传递给WinForm而不是单独注入的类,我可以将要传入的参数限制为只有一个。如果我这样做,它将使表示层依赖于自制的依赖注入项目,从而使表示层依赖于BLL和依赖注入项目。这可以接受吗?我还能做些什么来适应应用程序中依赖注入类的未来增长?
答案 0 :(得分:2)
但是,如果对象数量增长到5以上,那么这似乎是一个问题,那么我将向启动WinForm传递超过5个参数。
如果你注入超过5个依赖项,那表明你的班级做得太多了;责任太多了。它违反了Single Responsibility Principle。如果发生这种情况,您就开始考虑将类拆分为多个较小的类。例如,您可以将某些依赖项及其逻辑分组到Aggregate Services,或者您可以将我们的表单拆分为多个较小的组件/控件。 Rembember:关键是构图。
我决定将名为AppDependencyInjection的自制依赖注入容器传递给WinForm而不是单独注入的类。
你不应该这样做。这是一种称为服务定位器的模式,它具有many downsides。坚持依赖注入,只注入类直接需要的东西如果这很麻烦,例如因为类也有依赖性,你的代码/设计有问题(例如SRP违规)。
另请注意,建议您不要创建自己的DI库。这样的库将缺少可用的DI库为您提供的许多重要功能,但没有使用Pure DI(即手工布线对象图)的优势。你失去了编译时的支持,没有得到任何回报。
当您的应用程序很小时,您应该从Pure DI开始,一旦您的应用程序和DI配置增长到维持组合根变得麻烦,您可以考虑切换到已建立的DI库之一。
在你的情况下,你似乎处于中间位置。虽然依赖关系似乎来自一个常见的“依赖注入器”,但您仍然手动连接您的类而没有反射(即您明确地调用构造函数)。请注意,一旦开始使用反射,就可以使用其中一个已知的DI库了。