将记录器作为单身人士是一个好习惯吗? [英] Is it a good practice to have logger as a singleton?

查看:30
本文介绍了将记录器作为单身人士是一个好习惯吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个习惯将 logger 传递给构造函数,例如:

I had a habit to pass logger to constructor, like:

public class OrderService : IOrderService {
     public OrderService(ILogger logger) {
     }
}

但这很烦人,所以我已经使用它一段时间了:

But that is quite annoying, so I've used it a property this for some time:

private ILogger logger = NullLogger.Instance;
public ILogger Logger
{
    get { return logger; }
    set { logger = value; }
}

这也很烦人——它不干,我需要在每节课上重复这个.我可以使用基类,但又一次 - 我使用的是 Form 类,所以需要 FormBase 等.所以我想,暴露 ILogger 的单例会有什么缺点,所以人们会知道从哪里获得记录器:

This is getting annoying too - it is not dry, I need to repeat this in every class. I could use base class, but then again - I'm using Form class, so would need FormBase, etc. So I think, what would be downside of having singleton with ILogger exposed, so veryone would know where to get logger:

    Infrastructure.Logger.Info("blabla");

更新:正如 Merlyn 正确注意到的,我应该提到,在第一个和第二个示例中我使用的是 DI.

UPDATE: As Merlyn correctly noticed, I've should mention, that in first and second examples I am using DI.

推荐答案

这也很烦人 - 这不是 DRY

确实如此.但是,对于遍及您拥有的每种类型的跨领域关注点,您只能做很多事情.您必须在任何地方使用记录器,因此您必须拥有这些类型的属性.

That's true. But there is only so much you can do for a cross-cutting concern that pervades every type you have. You have to use the logger everywhere, so you must have the property on those types.

让我们看看我们能做些什么.

So lets see what we can do about it.

单身很糟糕.

我建议您坚持使用属性注入,就像您在第二个示例中所做的那样.这是最好的保理方法,无需求助于魔法.有一个显式的依赖比通过单例隐藏它更好.

I recommend sticking with property injection as you've done with your second example. This is the best factoring you can do without resorting to magic. It is better to have an explicit dependency than to hide it via a singleton.

但是如果单身人士为您节省了大量时间,包括您将不得不进行的所有重构(水晶球时间!),我想您可能能够忍受它们.如果曾经有单例的用途,这可能就是它.请记住,如果您曾经想改变主意,那么成本将与它获得的一样高.

But if singletons save you significant time, including all refactoring you will ever have to do (crystal ball time!), I suppose you might be able to live with them. If ever there were a use for a Singleton, this might be it. Keep in mind the cost if you ever want to change your mind will be about as high as it gets.

如果您这样做,请使用Registry 模式查看其他人的答案(参见描述),以及那些注册(可重置)单例 工厂 而不是单例记录器实例的.

If you do this, check out other people's answers using the Registry pattern (see the description), and those registering a (resetable) singleton factory rather than a singleton logger instance.

还有其他替代方案可能同样有效,但没有太多妥协,因此您应该先检查一下.

There are other alternatives that might work just as well without as much compromise, so you should check them out first.

您可以使用 Visual Studio 代码片段 加快那个重复代码的入口.您将能够输入诸如 loggertab 之类的内容,代码会神奇地为您显示.

You could use Visual Studio code snippets to speed up the entrance of that repetitive code. You will be able to type something like loggertab, and the code will magically appear for you.

您可以通过使用像 PostSharp 这样的面向方面编程 (AOP) 框架来消除一些属性注入代码 自动生成其中的一些.

You could eliminate a little bit of that property injection code by using an Aspect Oriented Programming (AOP) framework like PostSharp to auto-generate some of it.

完成后可能看起来像这样:

It might look something like this when you're done:

[InjectedLogger]
public ILogger Logger { get; set; }

您也可以使用他们的方法跟踪示例代码来自动跟踪方法入口和退出代码,这可能会消除将一些记录器属性全部添加在一起的需要.您可以在类级别或命名空间范围内应用该属性:

You could also use their method tracing sample code to automatically trace method entrance and exit code, which might eliminate the need to add some of the logger properties all together. You could apply the attribute at a class level, or namespace wide:

[Trace]
public class MyClass
{
    // ...
}

// or

#if DEBUG
[assembly: Trace( AttributeTargetTypes = "MyNamespace.*",
    AttributeTargetTypeAttributes = MulticastAttributes.Public,
    AttributeTargetMemberAttributes = MulticastAttributes.Public )]
#endif

这篇关于将记录器作为单身人士是一个好习惯吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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