我开始学习依赖注入,并决定尝试构建我自己的(简单)日志门面作为它的介绍。到目前为止,我已经使用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;
}
任何帮助或建议将不胜感激。 谢谢
答案 0 :(得分:0)
以下是考虑这个问题的一种方法:
首先,使表单类实现ILog
。这意味着它自己的形式是一个记录目的地。在窗体上调用日志记录方法时,写下您需要写入RichTextBox控件的内容。
现在,表单本身是ILog
,它还取决于ILog
。此外,我假设您还有另一个ILog
目的地要登录,例如Log4net适配器。
以下是我想象的对象图:
从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。