在下游产生新的Windows窗体时如何使用DI? [英] How to use DI when spawning new Windows Forms downstream?

查看:54
本文介绍了在下游产生新的Windows窗体时如何使用DI?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我让Unity DI容器最初与我的Windows Forms应用程序一起工作。在 Program.cs 中,我有以下内容:

I have the Unity DI container working initially with my Windows Forms application. In Program.cs I have the following:

static void Main()
{
    var container = BuildUnityContainer();
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(container.Resolve<MainForm>());
}

private static IUnityContainer BuildUnityContainer()
{
    var container = new UnityContainer();
    container.RegisterType<ITest, MyTestClass>();
    container.RegisterType<ISomeOtherTest, MyOtherClass>();
    return container;
}

在我的 MainForm 中构造函数我有以下起作用的

In my MainForm constructor I have the following which does work:

private readonly ITest test;

        public MainForm(ITest test)
        {
            this.test = test;
            InitializeComponent();
        }

容器已解析,代码正常运行。问题/问题是,如何从 MainForm 实例化一个新表单,比如说 Form2 具有以下构造函数:

The container is resolved and the code works fine. The problem / question is, how do I instantiate a new form from MainForm, say Form2 that has the following constructor:

private readonly ISomeOtherTest someOtherTest;

    public Form2(ISomeOtherTest someOtherTest)
    {
       this.someOtherTest = someOtherTest;
       InitializeComponent();
    }

如果我在 MainForm中尝试以下操作

Form2 form2 = new Form2();
form2.Show();

它会中断,抱怨我没有将值提供给构造函数。但是,我已经解决了我的容器,我认为所有下游容器都将得到解决。显然,我在这里缺少了一些东西,因为它不起作用。

It will break, complaining that I have not supplied the values to the constructor. However I have already resolved my container and I thought all downstream containers would be resolved. Obviously I'm missing something here though as it does not work.

这是否意味着我必须将所有依赖项预先加载到 MainForm 中表单不使用它,因此我可以将它们传递给我进行的任何新表单实例化?如果我有50个要解决的依赖项并具有顶层表单的构造函数来全部解决,那将很奇怪。请帮助清除我的理解,因为我几乎完全在Web API和MVC中使用了Unity和DI容器,而Web API和MVC已经为Controller内置了DI解析器,因此在这里我必须缺少一些知识和理解。

Does this mean I have to front load all dependencies into MainForm even if that form does not use it so I can then pass them to any new form instantiations I make? The would be weird if I had 50 dependencies to resolve and had the constructor for the top level form take them all. Please help clear up my understanding as I have used Unity and DI containers almost exclusively in Web API and MVC which already has the DI resolver built in for the Controllers, so I must be missing some pieces and understanding here.

推荐答案

您应该像这样创建表单

Form2 form = container.Resolve<Form2>();

您没有使用容器,因此Form没有没有参数的构造函数。如果使用容器解决它,它将检查构造函数,找到依赖项并自动为您注入依赖项。

You were not using the container, therefore the Form does not have a constructor which takes no arguments. If you resolve it with the container, it will examine the constructor, find the dependencies and automatically inject them into the constructor for you.

所以..也许您的问题是您无权访问MainForm中的容器?如果这是问题所在,则有两种方法。

So.. maybe your problem is that you do not have access to the container in your MainForm? If this is the problem there are two approaches..

将IUnityContainer注入MainForm构造函数中

但是...遵循 composition root模式的人们会告诉您,您只能使用应用程序根目录中的容器(在这种情况下,可能是Main())。另一种选择是...

However... people who live by the "composition root" pattern will tell you that you should only use the container from the root of your application (in this case, probably Main() ) The other option is...

从您的合成根目录(Main)创建一个Form2工厂类,该类将注入到MainForm中,并且MainForm使用工厂创建Form2

您应该阅读更多有关构图根的思维理论...

You should read more into the Composition Root theory of thinking...

组合根

更新

我以前从未做过,但是我认为第二种方法看起来像这样……

I've never had to do it before, but I think the second method would look something like this...

public class Form2Factory : IForm2Factory
{
    private readonly ISomeOtherTest someOtherTest;

    public Form2Factory(ISomeOtherTest someOtherTest)
    {
        this.someOtherTest = someOtherTest;
    }

    public Form2 Create()
    {
        return new Form2(someOtherTest);
    }
}


public class MainForm
{
    private readonly IForm2Factory form2Factory;

    public MainForm(IForm2Factory form2Factory)
    {
        this.form2Factory = form2Factory;
    }

    private void DoingSomething()
    {
        Form2 form = form2Factory.Create();
        form.Show();
    }
}

这篇关于在下游产生新的Windows窗体时如何使用DI?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆