Ninject在创建表单后注入winform?

时间:2016-10-12 11:02:19

标签: c# winforms logging dependency-injection ninject

我开始学习依赖注入,并决定尝试构建我自己的(简单)日志门面作为它的介绍。到目前为止,我已经使用Ninject使用NLog和log4net的基本功能。 (我知道Ninject有自己的测井门面,但这是一个学习练习)

但是我遇到了一个问题。我想要做的是复制我在RichTextBox中记录的文件(我使用winforms)。我可以直接使用NLog和log4net来做到这一点。我遇到的问题是,当Ninject连接接口时,它会在我的winform上的richtextbox创建之前创建一个记录器的实现,因此记录器找不到richtextbox。

我认为我需要做的是创建表单,然后让Ninject创建记录器并将其注入表单,但我不知道如何做到这一点。虽然我可能会以完全错误的方式看待这个问题?

请参阅下面的代码我用来将它们绑在一起:

static class Program
{
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        IKernel kernel = new StandardKernel(new DI.NLog.Logger());
        var form = kernel.Get<Form1>();
        Application.Run(form);
    }
}

,我的表单的构造函数是注入记录器的地方。

public Form1(ILog log)        
{
    InitializeComponent();            
    _log = log;
}

任何帮助或建议将不胜感激。 谢谢

1 个答案:

答案 0 :(得分:0)

以下是考虑这个问题的一种方法:

首先,使表单类实现ILog。这意味着它自己的形式是一个记录目的地。在窗体上调用日志记录方法时,写下您需要写入RichTextBox控件的内容。

现在,表单本身是ILog,它还取决于ILog。此外,我假设您还有另一个ILog目的地要登录,例如Log4net适配器。

以下是我想象的对象图:

Object Graph

从X到Y的箭头表示X取决于Y,或者Y被注入X.

CompositeLog类是composite ILog,它依赖于多个ILog对象,当它被调用来记录某些东西时,它会向所有{{1}广播这样的请求依赖。

从图中可以看出,我们有一个循环依赖。这可以通过使用Property Injection来解决。

我们可以在CompositeLog类中使用Property Injection,如下所示:

ILog

请注意,此类不会对构造产生任何依赖性。我们以后可以通过public class CompositeLog : ILog { private ILog[] logs; public ILog[] Logs { set { if(logs != null) throw new Exception("The logs dependencies has been set before"); logs = value; } } public void LogInformation(string message) { foreach(var log in logs) log.LogInformation(message); } //Other methods here //... } 属性注入其依赖项。

如果您使用Pure DI,则Composition Root将如下所示:

Logs

我不知道是否可以轻松地使用NInject完成此操作。绑定可能会很复杂。在there are multiple implementations of a single interface, I think that DI containers fail的情况下。我建议你使用Pure DI。