[Target("AS.Custom.NLogTarget")]
public class NLogCustomTarget : Target
{
private readonly ISessionContext _sessionContext;
private readonly IDbContext _dbContext;
public NLogCustomTarget(ISessionContext sessionContext, IDbContext dbContext)
{
this._sessionContext = sessionContext;
this._dbContext = dbContext;
}
protected override void Write(LogEventInfo logEvent)
{
AppLog log = new AppLog();
log.AppDomain = AppDomain.CurrentDomain.FriendlyName;
log.ClientIP = this._sessionContext.ClientIP;
log.Level = logEvent.Level.Name;
log.LoggerName = logEvent.LoggerName;
log.MachineName = Environment.MachineName;
log.Message = logEvent.FormattedMessage;
log.Username = this._sessionContext.UserName;
this._dbContext.Set().Add(log);
this._dbContext.SaveChanges();
}
}
Here the registration ;
IContainer _container;
ContainerBuilder builder = new ContainerBuilder();
_container = builder.Build();
builder = new ContainerBuilder();
builder.RegisterType()
.As()
.InstancePerRequest();
builder.RegisterType()
.As()
.InstancePerRequest();
builder.RegisterType()
.AsSelf()
.InstancePerLifetimeScope();
builder.Update(_container);
....
Unfortunately , this configuration is not enough to get constructor injection working on custom NLog target. The reason is , target class is created by NLog factory which has no information about the type registrations you have done or any information about your container. Luckily , NLog provides a delegate to setup your own instance creating method.
With a simple dependency resolver interface and implementation over the great Autofac IOC, i got it working.
Here is my implementation ;
IDependencyResolver :
///
/// Simple interface to create a dependency resolver
///
public interface IDependencyResolver
{
object GetService(Type serviceType);
}
My Custom Dependency Resolver Class:
public class ASAutofacDependencyResolver : IDependencyResolver
{
private readonly IContainer _container;
public ASAutofacDependencyResolver(IContainer container)
{
this._container = container;
}
public object GetService(Type serviceType)
{
return this.Scope().Resolve(serviceType);
}
private ILifetimeScope Scope()
{
try
{
if (HttpContext.Current != null)
return AutofacDependencyResolver.Current.RequestLifetimeScope;
return _container.BeginLifetimeScope(MatchingScopeLifetimeTags.RequestLifetimeScopeTag);
}
catch (Exception)
{
return _container.BeginLifetimeScope(MatchingScopeLifetimeTags.RequestLifetimeScopeTag);
}
}
}
Configuration of logger:
public static class LoggingConfigurator
{
private static readonly string NLogDefaultFileName = "NLog.config";
private static IDependencyResolver _resolver;
public static void SetResolver(IDependencyResolver resolver)
{
_resolver = resolver;
}
public static void ConfigureNLog()
{
ConfigurationItemFactory.Default.CreateInstance = (Type type) => _resolver.GetService(type);
string path = AppDomain.CurrentDomain.BaseDirectory + NLogDefaultFileName;
LogManager.Configuration = new XmlLoggingConfiguration(path, false);
}
}
LoggingConfigurator.SetResolver(new ASAutofacDependencyResolver(_container));
That is it!
No comments:
Post a Comment