Reputation: 353
I've created a .NET Core class library that defines utility class interfaces and that implements each interface for things like database access via ADO.NET, etc.
Each implementation class utilizes NLog. This works great in an ASP.NET Core Web application that includes and references the .NET Core class library.
However, when I try to instantiate these same implementation classes in the context of a .NET Core xUnit Test project, I get
Unable to cast object of type 'NLog.Logger' to type 'Microsoft.Extensions.Logging.ILogger'
I've searched for similar issues but found none.
In each class I've declared a private readonly variable:
private readonly ILogger<DatabasePersistenceAdoDotNet> _logger = null;
And I'm instantiating this variable like this:
_logger = (ILogger<DatabasePersistenceAdoDotNet>)NLog.Web.NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
This works in an ASP.NET Core Web application that includes and references the .NET Core class library but blows up in my .NET Core xUnit Test project.
I suspect that this has something to do with ASP.NET's dependency inject not being available in the .NET Core xUnit Test project, but I can't figure out how to make my utility package work correctly in both contexts.
Upvotes: 1
Views: 1998
Reputation: 36730
When using NLog with ASP.NET Core, there are two styles:
GetCurrentClassLogger()
When using .GetCurrentClassLogger()
, you wil get a NLog logger object (which implements NLog.ILogger
, not Microsoft.Extensions.Logging.ILogger
).
So if you need a Microsoft.Extensions.Logging.ILogger
, you can't use the .GetCurrentClassLogger()
. You need to:
Microsoft.Extensions.Logging.ILogger
, orOption 2 is the easy way and I will show you how:
// Load NLog
NLog.Web.NLogBuilder.ConfigureNLog("nlog.config");
// Create provider to bridge Microsoft.Extensions.Logging
var provider = new NLog.Extensions.Logging.NLogLoggerProvider();
// Create logger
Microsoft.Extensions.Logging.ILogger logger = provider.CreateLogger(typeof(MyClass).FullName);
Please note, you can't create a Microsoft.Extensions.Logging.ILogger<MyClass>
this way! Just a non-generic Microsoft.Extensions.Logging.ILogger
. If you need the generic version, then you need the DI setup and that will handle the conversion between both.
Also good to know, finding a nlog.config in a test project is hard, as unit test frameworks will move the binaries etc. I would recommend to use the config API
e.g.
var configuration = new LoggingConfiguration();
configuration.AddRuleForAllLevels(new ConsoleTarget());
LogManager.Configuration = configuration;
OR
var configuration = XmlLoggingConfiguration.CreateFromXmlString("<nlog>....</nlog>"); //full nlog.config as string
LogManager.Configuration = configuration;
Upvotes: 5