我有一个包含以下不同层的Web api解决方案。我想在我的项目中实现unity log4net扩展,并希望在不同的层中使用它。
我是否仅需要在作为主要入口的Web层中安装log4net软件包?还是应该将其安装在所有层上?
答案 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。如果设计正确,则只有合成根目录才需要了解任何外部依赖项。