2

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

包含方法Icomponent的接口save()

以及许多实现它的类。

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

更新

我有几个设计想法:

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

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

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

使用装饰器模式Icomponent和其他log()方法。

创建LogService从每个装饰器调用的类log()

  • AOP——面向方面编程

我读过一点,但不知道。

它适用于 c# 吗?

  • 您对该解决方案的设计是什么?

更新2

看了代码,发现还有一层接口

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

I_AComponente : IComponente

I_BComponente : IComponente

A : I_AComponente

B : I_BComponente
4

2 回答 2

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从单元测试的角度来看,来自哪里将是无关紧要的。

此外,您应该检查现有的记录器,而不是滚动您自己的记录器,例如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可能仍然是静态类,但它可以简单地提供非静态记录器(并管理它们的生命周期/范围)。这根本不会使单元测试变得困难。

于 2012-05-09T19:22:35.270 回答
0

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

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

于 2012-05-10T11:23:07.827 回答