它是一个很好的做法,有记录作为一个单身? [英] Is it a good practice to have logger as a singleton?

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

问题描述

我有一个习惯,通过记录仪的构造函数,如:

 公共类OrderService的:IOrderService {
     公共OrderService的(ILogger记录器){
     }
}
 

但是,这是很烦人的,所以我用了一段时间的属性这样的:

 私人ILogger记录= NullLogger.Instance;
公共ILogger记录仪
{
    {返回记录; }
    集合{记录=价值; }
}
 

这是越来越讨厌过 - 它不是干的,我需要在每类重复这一点。我可以使用的基类,但话又说回来 - 我使用Form类,所以需要FormBase等。 因此,我认为,这将是有单用ILogger暴露的缺点,所以veryone会知道从哪里得到记录器:

  Infrastructure.Logger.Info(布拉布拉);
 

更新:由于Merlyn正确地注意到了,我已经应该提到,在第一和第二个例子我使用DI

解决方案
  

这是越来越讨厌过 - 它不是

这是真的。但只有这么多,你可以为一个跨领域的关注,遍及每一个类型的,你必须做的。你要的使用的记录器无处不在,所以你必须对这些类型的属性。

所以让我们看看我们能做些什么。

辛格尔顿

单身是可怕的<阻燃西装式>

我建议与地产注入坚持为你与你的第二个例子完成。这是你而不是诉诸魔法能做的最好的保理业务。最好是有明确的相关性,而不是通过一个单隐藏。

但是,如果单身人士为您节省显著的时间,包括所有的重构,你永远不会有做(水晶球的时间!),我想你也许能和他们住在一起。如果说真的有一个辛格尔顿一用,这可能是它。请记住成本,如果你的永远的想改变主意,将有约高,因为它得到。

如果你做到这一点,使用注册模式(见说明),以及注册一个(可复位)单身的工厂的而不是一个单记录器实例。

有可能会很好的工作不一样多的妥协其他的替代品,所以你应该先检查出来。

的Visual Studio code片段

您可以使用的Visual Studio code片段加快了重复code入口。您可以键入类似记录 <大骨节病>标签,和code会奇迹般地出现了你。

使用AOP擦干

您可以消除的,物业注入code稍微利用的面向方面编程(AOP)框架,比如PostSharp 自动生成一些吧。

这可能是这个样子的时候,你就大功告成了:

  [InjectedLogger]
公共ILogger记录器{获得;组; }
 

您也可以使用他们的方法跟踪样本code 以自动跟踪方法的入口和出口code ,这可能不再需要添加一些记录器的属性都在一起。你可以在类级别应用属性,或命名空间广阔:

  [追踪]
公共类MyClass的
{
    // ...
}

// 要么

#如果调试
[总成:跟踪(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

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

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