在解决方案中在不同层中使用log4net的最佳方法是什么

时间:2018-11-16 18:01:24

标签: c# asp.net-web-api log4net

我有一个包含以下不同层的Web api解决方案。我想在我的项目中实现unity log4net扩展,并希望在不同的层中使用它。

  • DL
  • BL
  • Web(包含控制器类并使用Unity for IOC)
  

我是否仅需要在作为主要入口的Web层中安装log4net软件包?还是应该将其安装在所有层上?

1 个答案:

答案 0 :(得分:0)

只有Web(应用程序入口点)确实需要引用第三部分的依赖关系

正如我在您之前的一个问题中所解释的那样。

为您的自定义记录器创建一个核心项目

public interface ILogger {
    //...
}

所有其他项目都将引用该代码项目并利用日志记录抽象。

例如,以下是在数据层中

public class ExampleRepository : IRepository {
    private readonly ILogger logger;

    public ExampleRepository(ILogger logger){
        this.logger = logger;
    }

    //...use logger
}

数据层无需引用外部依赖项,因为它仅依赖于自定义抽象。

进一步说,业务层具有以下服务

public class ExampleService: IService {
    private readonly ILogger logger;
    private readonly IRepository repository;

    public ExampleService(IRepository repository, ILogger logger){
        this.logger = logger;
        this.repository = repository;
    }

    //...use logger and repository
}

业务层无需引用外部依赖关系,因为它也仅依赖于自定义抽象。

在最高级别上是Web项目。再次假设一个简单的控制器

public class ExampleController: Controller {
    private readonly ILogger logger;
    private readonly IService service;

    public ExampleController(IService service, ILogger logger){
        this.logger = logger;
        this.service = service;
    }

    //...use logger and service
}

在整个示例中,所有类都依赖于抽象而不是实现方面的问题。

您想使用log4net作为整个系统的日志记录实现,因此Web项目引用必要的依赖项,然后创建

public class Log4NetWrapper : ILogger {
    private readonly ILog log; //log4net 

    public Log4NetWrapper(ILog log) {
        this.log = log;
    }

    public void LogMessage(string msg) {
        log.Info(msg);
    }

    //...
}

这时,只有Web项目才需要引用第三方依赖性。

现在,任何时候依赖类要使用通过log4net完成的日志记录。

太好了,在Web项目的组合根目录中,注册抽象和实现以及使用log4net所需的任何扩展。

container = new UnityContainer();
container.AddNewExtension<Log4NetExtension>();
container.RegisterType<ILogger, Log4NetWrapper>(new HierarchicalLifetimeManager());

因此,现在无论何时需要从容器中解析ExampleController时,Log4NetWrapper都会注入到Web项目中当前正在执行的整个对象图中。

在这种情况下,log4net是实现问题。由于上面的设计,所有涉及的类都只关注抽象而不是具体。

长话短说,

  

我是否仅需要在作为主要入口的Web层中安装log4net软件包?

  

还是应该将其安装在所有层中?

如果您的架构经过精心设计,则

在整个示例中都使用了

DI。如果设计正确,则只有合成根目录才需要了解任何外部依赖项。