【发布时间】:2020-11-25 15:02:51
【问题描述】:
现在我正在创建一个 Web 服务并开始使用 NLog 记录器。我对其进行了配置,并且在这样的 Web 服务项目中使用它时它可以工作:
[ApiController]
public class SimpleController : BaseController<SimpleApi>
{
private readonly ILogger<SimpleController > _logger;
public MarcatgeController(ILogger<SimpleController > logger, IServiceProvider provider) : base(provider)
{
_logger = logger ?? throw new NullReferenceException(nameof(logger));
}
[HttpPost]
public async Task<IActionResult> SimpleMethod([FromBody]Request request)
{
_logger.LogInformation("SimpleMethod");
return ParseResponse(await CurrentApi.SimpleMethod(request));
}
}
但是在项目 API 上使用它时(当它调用 CurrentApi 时)没有任何记录:
public class SimpleApi: BaseApi
{
private readonly ILogger<SimpleApi> _logger;
public MarcatgeApi(ILogger<SimpleApi> logger)
{
_logger = logger ?? throw new NullReferenceException(nameof(logger));
}
public Task<Response<ResponseSimple> SimpleMethod(Request request)
{
_logger.LogDebug($"SimpleApi -> SimpleMethod()");
return GetResponseSuccess<ResponseSimple>(resp);
}
}
基本控制器类如下所示:
public class BaseController<T> : Controller where T : BaseApi
{
protected T CurrentApi { get; private set; }
public BaseController(IServiceProvider provider)
{
CurrentApi = (T)ActivatorUtilities.CreateInstance(provider, typeof(T));
}
}
如果我在 API 项目上使用 NLog.Logger log = NLog.LogManager.GetCurrentClassLogger(); 它可以工作,但我想将它注入到构造函数中,我该怎么做?
我尝试将包 NLog 添加到我想使用记录器的所有项目中,就像这个 question 的解决方案一样,但仍然没有工作。
编辑:我如何注册 NLog:
public static void Main(string[] args)
{
var logger = NLogBuilder.ConfigureNLog("NLog.config").GetCurrentClassLogger();
try
{
logger.Debug("init main");
CreateHostBuilder(args).Build().Run();
}
catch (Exception exception)
{
//NLog: catch setup errors
logger.Error(exception, "Stopped program because of exception");
throw;
}
finally
{
NLog.LogManager.Shutdown();
}
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
})
.UseNLog();
}
Api模块注册:
public class ApiModule
: Autofac.Module
{
public ApiModule()
{
}
protected override void Load(ContainerBuilder builder)
{
try
{
builder.RegisterType<BaseApi>();
builder.RegisterType<BaseAuthApi>();
builder.RegisterType<MarcatgeApi>();
var mapper = MappingProfile.InitializeAutoMapper().CreateMapper();
// Registrem mapper
builder.RegisterInstance<IMapper>(mapper);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
【问题讨论】:
-
只需要在DI框架中注册Nlog即可。这似乎是一个很好的指南:github.com/NLog/NLog/wiki/…。第 4 部分似乎是您缺少的部分。
-
对不起,我忘了说明我是如何注册 NLog 的,但它的完成方式与链接完全一样,但仍然无法正常工作
-
您似乎使用
Activator.CreateInstance手动创建这些api,这不使用DI 或任何东西。为什么不使用CurrentApi = provider.GetRequiredService<T>();? (记得注册你的 api!) -
通常你也想避免注入
IServiceProvider只是让构造函数要求它想要的东西。 -
尝试将
LogDebug更改为LogWarning。另见github.com/NLog/NLog.Web/wiki/…
标签: c# asp.net-core dependency-injection nlog ilogger