Asp.net web api 使用Unity根据其使用者/上下文依赖注入特定依赖项

Asp.net web api 使用Unity根据其使用者/上下文依赖注入特定依赖项,asp.net-web-api,dependency-injection,unity-container,nlog,Asp.net Web Api,Dependency Injection,Unity Container,Nlog,我正在使用Nlog作为Web API项目中的日志框架,其中包含Unity一个s IoC容器 我有一个LoggingService类,它将类名作为参数,并返回NLog的一个实例。为此,我使用了依赖注入 问题:我很困惑如何将类名传递给我的日志服务类 代码: 使用NLog; 命名空间Portal.Util.Logging { 公共类日志服务:ILoggingService { 专用只读ILogger\u记录器; 公共日志服务(字符串currentClassName) { _logger=LogMana

我正在使用
Nlog
作为Web API项目中的日志框架,其中包含
Unity
一个s IoC容器

我有一个
LoggingService
类,它将类名作为参数,并返回NLog的一个实例。为此,我使用了依赖注入

问题:我很困惑如何将类名传递给我的
日志服务

代码:

使用NLog;
命名空间Portal.Util.Logging
{
公共类日志服务:ILoggingService
{
专用只读ILogger\u记录器;
公共日志服务(字符串currentClassName)
{
_logger=LogManager.GetLogger(currentClassName);
}
public void FirstLevelServiceLog(字符串日志)
{
_logger.Log(LogLevel.Debug,Log);
}
}
公共接口ILoggingService
{
void FirstLevelServiceLog(字符串日志);
}
}
服务层:(这是从控制器调用的)

公共类MyService:IMyService
{
私人只读ILoggingService(日志服务);;
公共MyService(iLogginService loggingService)
{
_loggingService=loggingService
}
公共剂量测定法()
{
_loggingService.FirstLevelServiceLog(“调试”);
}
}
团结:

var container=newunitycontainer();
container.RegisterType(新注入构造函数(“”)
/*不确定如何在此处传递类名*/

一种方法是使用名称注册

您首先注册所有记录器,并为每个记录器命名

使用
InjectionConstructor
注入参数值

var ctr = new UnityContainer();

// You can add lifetimemanagers as well
ctr.RegisterType<ILoggingService, LoggingService>("Class1Logger",new InjectionConstructor("Class1"));
ctr.RegisterType<ILoggingService, LoggingService>("Class2Logger", new InjectionConstructor("Class2"));
这就是你所需要做的

我通常认为按名称注册并不是最好的做法,我大多数时候更喜欢某种虚拟接口继承(因为我不喜欢将相同的接口类型映射到具体类型)。 但在这种情况下,它看起来是一种体面而干净的解决问题的方法


如果希望自动注册,可以使用某种反射(自定义属性或基于
ILogger
的实现)并自动注册所有实例。

这看起来像是隐藏在一个问题背后的设计问题

日志服务需要进行一些重构,以便更容易地注入所需的行为

引入从基本
ilogingservice

公共接口ILOGingService:ILOGingService{
}
公共接口ILoggingService{
void FirstLevelServiceLog(字符串日志);
}
重构当前实现以依赖于服务的通用版本

公共类日志服务:ILoggingService{
专用只读ILogger\u记录器;
公共日志服务(){
字符串currentClassName=typeof(TType).Name;
_logger=LogManager.GetLogger(currentClassName);
}
public void FirstLevelServiceLog(字符串日志){
_logger.Log(LogLevel.Debug,Log);
}
}
这将允许使用类型参数来确定日志管理器的类名称

现在,那些依赖于日志服务的人可以通过构造函数注入来明确他们的依赖关系

公共类MyService:IMyService{
私人只读ILoggingService(日志服务);;
公共MyService(iLogginService loggingService){
_loggingService=loggingService
}
公共剂量测定法(){
_loggingService.FirstLevelServiceLog(“调试”);
}
}
请注意,唯一需要重构的是构造函数的泛型参数,因为泛型记录器是从基本
ilogingservice
派生的

日志服务抽象最终可以使用开放泛型注册以实现它

var container=newunitycontainer();
RegisterType(typeof(ilogingservice),typeof(LoggingService));
这样,就不需要为系统中使用的每个记录器注册单独的实现

public class MyLogic1
{
    public MyLogic1([Dependency("Class1Logger")]ILoggingService logger)
    {

    }
}

public class MyLogic2
{
    public MyLogic2([Dependency("Class2Logger")]ILoggingService logger)
    {

    }
}