0

我们的团队创建了一个库,可自动执行 WCF 服务的异常处理和日志记录。使用这个库,开发人员只需用自定义属性装饰服务,设置一些简单的配置文件条目,他们就可以利用通用的异常处理和日志记录机制。

以下是如何使用该库的示例:

[ErrorHandlingBehavior (LogWriterOption.EmailLogWriter, LogWriterOption.SQLLogWriter)]
public class SampleService : ISampleService
{
    public string GetData(int value)
    {
        throw new DivideByZeroException();
        //return string.Format("You entered: {0}", value);
    }
}

ErrorHandlingBehavior 类使用 Logger 对象,该对象接受参数中的 LogWriterOption 枚举来确定记录的位置。

我们的初衷是让开发者指定自己的日志记录机制,并将其提供给ErrorHandlingBehavior,从而消除解决方案对Logger类的依赖(取而代之的是任何实现ILogger的类)。但是,以以下方式指定属性会产生错误:

 [ErrorHandlingBehavior (new Logger (new HashSet<LogWriterOptions> 

                             {LogWriterOption.EmailLogWriter, LogWriterOption.SQLLogWriter}))]

似乎我们在指定属性时无法实例化任何东西,因此我们现在无法让用户指定他们自己的日志记录机制。

有人知道解决这个问题的方法吗?我们如何将实现 ILogger 的类的实例提供给我们的属性,而不是硬连接依赖关系?

4

2 回答 2

1

我还写了一些日志异常处理行为。在这种情况下,我总是问自己:

log4net 会做什么?

您的 LogWriterOptions 似乎转换为 log4net 附加程序。Appender 通常最好通过 xml 配置来完成,因为它们的要求会随环境而变化。(它相当于不要将 WCF 客户端绑定放入代码中。)换句话说,在本地开发时:不要发送电子邮件,只输出到本地文本文件。在 QA 中运行时:输出到数据库,但不要与测试人员一起发送电子邮件,故意破坏某些东西。在生产中:做一些完全不同的事情。Log4net appenders 支持所有这些类型的编译后更改(以及更多)。

回到你的问题:

  • 在您的方法中,我会将行为名称作为“StandardLogging”之类的字符串传递给 ErrorHandlingBehavior,这将查找导致使用 EmailLogWriter 和 SQLLogWritter 的可配置行为。
  • 日志框架中常见的另一种方法是传递正在记录的类的类型。如果该类型没有显式配置,它将获取默认附加程序。

请注意,这种配置方法的额外好处是

  1. 集中整个应用程序的日志记录输出选项。如果您更改标准,则不必更新许多类文件。
  2. 标准化不同代码段使用的日志写入器选项。在代码审查会议上,您只需问“您是否使用标准日志记录输出?” 查看。

更新以响应您的“保持简单”评论:

如果保持简单是目标,我想说什么都不传递给你的行为的构造函数。而是将所有 log4net 配置信息放在它自己的 log4net.config 文件中,并将其作为通用日志库的一部分存储在源代码控制中。然后只需要添加新项目(或初级开发人员)

<configuration>
     <log4net configSource="log4net.config" />
</configuration> 

到 app.config。这种方法的好处是,作为我们构建过程的一部分,我们定义了不同的 log4net.config 文件以部署到不同的环境。

于 2013-02-19T23:54:22.497 回答
0

您可以使用工厂模式。让开发人员指定将用于提供ILogger实例的类型:

[ErrorHandlingBehavior(LoggerFactoryType = "FooBar.MyLoggerFactory")]

这种类型可以实现你的接口:

public interface ILoggerFactory
{
    ILogger GetLogger();
}

然后在您的自定义属性中,您可以首先使用该Type.GetType方法获取工厂类型,检查它是否实现了ILoggerFactory接口,使用该Activator.CreateInstance方法实例化工厂,最后GetLogger在该实例上调用该方法。

于 2013-02-19T07:34:36.150 回答