将LogService添加到我的应用程序

时间:2012-05-09 15:49:52

标签: c# unit-testing design-patterns .net-3.5 singleton

我有一个应用程序(旧版代码)

包含Icomponent方法的接口save()

以及许多实现它的类。

我想在每次save()之后添加日志。

updae

我的设计思路很少:

  • Singelton Logger - 将在每次可记录的操作后调用

我认为LogService是singelton的经典案例,但我认为它很难进行单元测试。

  • 使用Ioc的装饰器+记录器初始化

使用额外的Icomponent方法将装饰器模式用于log()

创建从每个装饰器的LogService

调用的log()
  • AOP - 面向方面编程

我读了一下这个,但不知道。

是否适用于c#?

  • 你的解决方案是什么设计?

UPDATE2

阅读完代码后,我看到还有另一层接口

在混凝土层之前。我不认为我应该装饰每个特定的界面。正确?

I_AComponente : IComponente

I_BComponente : IComponente

A : I_AComponente

B : I_BComponente

2 个答案:

答案 0 :(得分:1)

它根本不必是单身人士。考虑:

public void ComponentDecorator : IComponent
{
    private IComponent component;
    private ILogger logger;

    public ComponentDecorator(IComponent component, ILogger logger)
    {
        this.component = component;
        this.logger = logger;
    }

    public void Save()
    {
        this.component.Save();
        this.logger.Log("Some important message");
    }
}

因为无论如何你都会将装饰组件注入装饰器,也可以注入logger(这样很容易测试)。 logger来自哪里与单元测试的角度无关。

此外,您应该检查现有的记录器,而不是滚动自己的记录器,例如Apache log4net

修改

单例记录器难以测试的说法可能来自于C#中的单例通常会在某处使用static字段或静态类实现的事实。说你有:

public static LoggerService
{
    public static Log(string message) { ... }
}

现在,在你的装饰者的方法中,你可能需要按照以下方式做点什么:

public void Save()
{
    this.component.Save();
    LoggerService.Log("Some important message");
}

这使得Save方法的测试几乎不可能,因为您在方法中具有紧密耦合的依赖关系。如果您可以将LoggerService配置为不写入文件系统的测试(但仍然是解决问题而不是解决问题),这并不是很糟糕。

通过接口注入中,问题自然消失了。 LoggerService可能仍然是静态类,但它可以简单地提供非静态记录器(并管理它们的生命周期/范围)。这根本不会使单元测试变得困难。

答案 1 :(得分:0)

是的! AOP适用于C sharp http://www.developerfusion.com/article/5307/aspect-oriented-programming-using-net/

AOP是避免在代码中编写Log语句的好方法。这是一个如何在您的应用程序中实现AOP的示例....但是,在以下链接中提供的方法的唯一缺点是您还需要配置Castle Windsor http://ayende.com/blog/3474/logging-the-aop-way