我是 Dependency Injection 的新手,并且一直在玩 Ninject 尝试制作小型测试应用程序来了解这些概念。Mark Seemann 的.NET 中的依赖注入是我阅读列表中的下一个。
我在简短的测试中遇到的一个问题是,我不知道如何处理类可以实例化其类型的新实例的情况。一个示例是带有按钮的表单。当用户单击按钮时,表单会创建另一个相同类型的表单。
如果不使用 DI,在上述场景中,您只需new
在原始表单的 click 事件处理程序中创建另一个表单实例。我的理解(我在这方面可能很天真)首选方法是使用抽象工厂来创建实例并让类依赖它。
下面是我尝试过的代码(与表单无关,只是普通类)由于循环依赖关系而无法工作,我确实明白为什么会发生这种情况。我只是想不出一个不需要我new
手动完成的好解决方案。我觉得我错过了一个关键部分。
public interface IMainClass
{
IMainClass CreateNew();
void Do();
}
public interface IMainClassFactory
{
IMainClass CreateNew();
}
public class MainClassFactory : IMainClassFactory
{
private readonly IMainClass _mainClass;
public MainClassFactory(IMainClass mainClass)
{
_mainClass = mainClass;
}
public IMainClass CreateNew()
{
return _mainClass;
}
}
public class MainClass : IMainClass
{
private readonly IMainClassFactory _mainClassFactory;
public MainClass(IMainClassFactory mainClassFactory)
{
_mainClassFactory = mainClassFactory;
}
public IMainClass CreateNew()
{
return _mainClassFactory.CreateNew();
}
public void Do()
{
Console.WriteLine("Do from Main Class");
}
}
public class Program
{
public static void Main()
{
IKernel kernel = new StandardKernel();
kernel.Bind<IMainClassFactory>().To<MainClassFactory>();
kernel.Bind<IMainClass>().To<MainClass>();
var mainClassFactory = kernel.Get<IMainClassFactory>();
var mainClass = mainClassFactory.CreateNew();
mainClass.Do();
Console.WriteLine("Press <ENTER> to exit...");
Console.ReadLine();
}
}
我知道这段代码不正确。
- IMainClass 是否应该实现 IMainClassFactory?有关系吗?
kernel.Bind<IMainClass>().To<MainClass>();
似乎不对,但我不知道该怎么办new
完全禁止你自己的对象吗?- 我想我很好地掌握了不使用服务定位器反模式的方法。我不希望我的班级知道任何 IOC 容器。
我确信这些类型的场景一直在发生,所以我正在寻找一般情况下的首选解决方案。如果可能的话,我想避免使用任何特定于 Ninject 的奇异特性,以防我想转向不同的实现。
编辑1: “检测到Autofac Circular Component Dependency”错误 这个问题看起来很相似,但接受的答案似乎是在提倡服务定位器?也许我读错了,但看起来它违反了好莱坞原则