将logger作为单身吗? [英] Is it a good practice to have logger as a singleton?

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

问题描述

我习惯于将logger传递给构造函数,如:

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

但这是很讨厌,所以我已经使用了一段时间的属性:

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

这也变得烦人 - 它不干,我需要重复这在每一个班级。我可以使用基类,但是再次 - 我使用Form类,所以需要FormBase等
所以我认为,在ILogger暴露的单例中会有什么不利之处,所以很有可能会知道在哪里logger:

  Infrastructure.Logger.Info(blabla); 

更新:正如Merlyn正确注意到的那样,我应该提到,在第一和第二个例子中使用DI。

解决方案


这也变得烦人 - 它不是 DRY


那是真正。但是,只有这么多,你可以做一个跨部门的关切,渗透你所有的类型。您必须使用记录器到所有地方,所以您必须具有这些类型的属性。



所以让我们看看我们可以做什么。



Singleton



单身人士是可怕的< flame-suit-on>



我建议坚持使用属性注入,就像完成第二个例子一样。这是您不用诉诸魔法就能做的最好的因子。但是,如果单身人士节省了大量的时间,包括所有重构,你将永远不得不做(水晶球时间!),我想你可能能够和他们一起生活。如果有一个单身人士的使用,这可能是。请记住,如果您希望改变主意,您的想法将会达到最高水平。



如果您这样做,请检查使用 注册表模式了解其他人的答案(请参阅说明),以及注册(可重设)单身工厂而不是单例记录器实例的那些。



还有其他替代方法工作也没有那么多的妥协,所以你应该先检查出来。



Visual Studio代码片段



您可以使用 Visual Studio代码段加快重复代码的入口。您将能够输入类似 logger 标签的内容,代码将会神奇地显示给您。



使用AOP来关闭



您可以使用面向对象编程(AOP)框架,如PostSharp ,以自动生成一些。



它可能会看起来完成这样的事情:

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

您还可以使用他们的方法跟踪示例代码,以自动跟踪方法的入口和退出代码,这可能会消除添加一些记录器属性的需要。您可以在类级别或命名空间广泛应用该属性:

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

//或

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


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; }
}

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");

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

解决方案

This is getting annoying too - it is not 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.

Singleton

Singletons are terrible <flame-suit-on>.

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.

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 code snippets

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.

Using AOP to DRY off

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

这篇关于将logger作为单身吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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