2

我是 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”错误 这个问题看起来很相似,但接受的答案似乎是在提倡服务定位器?也许我读错了,但看起来它违反了好莱坞原则

4

1 回答 1

0

从纯 DI 的角度来看,抽象工厂将是正确的方法,但也许您在这里遗漏了一个模式:

当用户单击按钮时,表单会创建另一个相同类型的表单。

表单不应直接依赖于其他表单。这将它们硬连接在一起。应该有一个集中点来处理屏幕导航和应用程序的流程。换句话说,您缺少的是Application Controller

你的表格应该取决于一个IApplicationController或类似的东西。此应用程序控制器可能再次依赖于创建新表单的抽象工厂。

于 2012-10-04T18:40:11.200 回答