这也让人恼火——不是DRY
没错.但对于一个贯穿于你所有类型的跨领域问题,你能做的只有这么多.你必须在所有地方安装use个记录器,所以你必须拥有这些类型的属性.
让我们看看我们能做些什么.
单例
单身汉是可怕的<flame-suit-on>
人.
我建议坚持使用属性注入,就像您在第二个示例中所做的那样.这是您在不诉诸魔法的情况下所能做的最好的因式分解.具有显式依赖项比通过单例隐藏它要好.
但是,如果单身能为你节省大量时间,包括你必须做的所有重构(水晶球时间!),我想你也许能和他们住在一起.如果说单身有什么用处的话,这可能就是了.请记住,如果你想改变主意,你的成本将是最高的.
如果您这样做,请使用the Registry
pattern(参见说明)判断其他人的答案,并判断那些注册了(可重置的)单例factory而不是单例记录器实例的人的答案.
还有其他替代方案可能也同样有效,但不会有太多妥协,所以你应该先看看它们.
Visual Studio代码片段
你可以用Visual Studio代码片段来加速重复代码的输入.你可以输入logger
标签之类的内容,代码就会神奇地出现在你面前.
使用面向方面编程(AOP)来烘干
通过使用an Aspect Oriented Programming (AOP) framework like PostSharp自动生成一些属性注入代码,可以消除一点属性注入代码.
当您完成后,它可能看起来像这样:
[InjectedLogger]
public ILogger Logger { get; set; }
您还可以使用their method tracing sample code自动跟踪方法入口和出口代码,这样就不需要同时添加一些记录器属性.可以在类级别或命名空间范围内应用该属性:
[Trace]
public class MyClass
{
// ...
}
// or
#if DEBUG
[assembly: Trace( AttributeTargetTypes = "MyNamespace.*",
AttributeTargetTypeAttributes = MulticastAttributes.Public,
AttributeTargetMemberAttributes = MulticastAttributes.Public )]
#endif