依赖于log4net的记录器,并使用温莎城堡检索记录仪由主叫类型 [英] Dependency on Log4Net Logger and Retrieve Logger by Caller Type using Castle Windsor

查看:211
本文介绍了依赖于log4net的记录器,并使用温莎城堡检索记录仪由主叫类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我身边有 log4net的薄的包装,我尝试使用调用类的类型来从 log4net.LogManager <记录仪/ code>通过使用 Castle.Windsor

 公共类Foo:IFoo的
{
    私人只读ICommonLog _logger;

    公共美孚(ICommonLog记录仪)
    {
        _logger =记录;
    }

    公共无效FooBar的()
    {
        _logger.Info(输入FooBar的方法);
    }
}

公共类CommonLog:ICommonLog
{
    私人只读log4net.ILog _logger;

    公共CommonLog(类型loggerType)
    {
        _logger = log4net.LogManager.GetLogger(loggerType);
    }

    公共无效信息(字符串消息)
    {
        _logger.Info(message.Cleanse());
    }

    // ...
}
 

我已经尝试了本登记 Castle.Windsor (2.5.1),我能得到正确的记录器。上午我错使用动态参数,对于这种情况?有没有更好的解决方案?

  container.Register(Component.For&LT; ICommonLog&GT;()ImplementedBy(typeof运算(CommonLog))。
   LifeStyle.Transient);
container.Register(Component.For&LT;的IFoo&GT;()ImplementedBy(typeof运算(富))。
   LifeStyle.Transient.DynamicParameters(
       (K,D)=&GT;
       {
          无功分量= k.Resolve&LT; ICommonLog&GT;(新{loggerType = typeof运算(富)});
          D [记录仪] =组件;
          返回R =&GT;
          {
              如果(分量!= NULL)
              {
                  r.ReleaseComponent(组分);
              }
          };
       })
  );
 

编辑:我已经更新使用该解决方案 ISubDependencyResolver

 公共类LoggerResolver:ISubDependencyResolver
{
    私人只读的iKernel内核;

    公共LoggerResolver(的iKernel内核)
    {
        this.kernel =内核;
    }

    公共BOOL CanResolve(CreationContext的背景下,
                           ISubDependencyResolver contextHandlerResolver,
                           ComponentModel模式,
                           DependencyModel依赖性)
    {
        返回dependency.TargetType == typeof运算(ICommonLog);
    }

    公共对象解析(CreationContext的背景下,
                          ISubDependencyResolver contextHandlerResolver,
                          ComponentModel模式,
                          DependencyModel依赖性)
    {
        如果(CanResolve(背景下,contextHandlerResolver,模型,依赖))
        {
            返回kernel.Resolve&其中; ICommonLog&GT;(新{loggerType = model.Implementation});
        }
        返回null;
    }
}
 

报名方式:

  container.Register(Component.For&LT; ICommonLog&GT;()ImplementedBy(typeof运算(CommonLog))
    .LifeStyle.Transient);
container.Register(Component.For&LT;的IFoo()ImplementedBy(typeof运算(富))
    .LifeStyle.Transient);
container.Kernel.Resolver.AddSubResolver(新LoggerResolver(container.Kernel));
 

解决方案

您并不需要注册CommonLog。你分依赖解析器可以新一轮上涨给你。

<$p$p><$c$c>container.Register(Component.For<IFoo>().ImplementedBy<Foo>().LifeStyle.Transient); container.Kernel.Resolver.AddSubResolver(新LoggerResolver(container.Kernel)); 公共类LoggerResolver:ISubDependencyResolver {     ...     公共对象解析(CreationContext背景下,ISubDependencyResolver contextHandlerResolver,ComponentModel模型,DependencyModel依赖)     {         //无需能够解决,温莎会为你做这个         返回新CommonLog(model.Implementation);     } }

记录仪提供的编辑为例

<$p$p><$c$c>container.Register(Component.For<ILoggerProvider>().ImplementedBy<Log4NetLoggerProvider &GT;()LifeStyle.Transient); 公共接口ICommonLoggerProvider {     ICommonLog GetLogger(类型类型); } 公共类Log4NetLoggerProvider:ICommonLoggerProvider {     公共ICommonLog GetLogger(类型类型)     {         返回新Log4NetLogger(类型);     } } 公共类LoggerResolver:ISubDependencyResolver {     ...     公共对象解析(CreationContext背景下,ISubDependencyResolver contextHandlerResolver,Castle.Core.ComponentModel模型,DependencyModel依赖)     {         返回kernel.Resolve&LT; ICommonLoggerProvider&GT;()GetLogger(model.Implementation);     } }

I have a thin wrapper around log4net and I am trying to use the type of the calling class to get a logger from log4net.LogManager by using Castle.Windsor.

public class Foo: IFoo
{
    private readonly ICommonLog _logger;

    public Foo(ICommonLog logger)
    {
        _logger = logger;
    }

    public void FooBar()
    {
        _logger.Info("Enter FooBar Method");
    }
}

public class CommonLog : ICommonLog
{
    private readonly log4net.ILog _logger;

    public CommonLog(Type loggerType)
    {
        _logger = log4net.LogManager.GetLogger(loggerType); 
    }

    public void Info(string message)
    {         
        _logger.Info(message.Cleanse());
    }

    // ...
}

I have tried this registration in Castle.Windsor (2.5.1) and I am able to get the correct logger for Foo. Am I mis-using dynamic parameters for this scenario? Is there a more elegant solution?

container.Register(Component.For<ICommonLog>().ImplementedBy(typeof(CommonLog)).
   LifeStyle.Transient);
container.Register(Component.For<IFoo>().ImplementedBy(typeof(Foo)).
   LifeStyle.Transient.DynamicParameters(
       (k, d) =>
       {
          var component = k.Resolve<ICommonLog>(new {loggerType = typeof (Foo)});
          d["logger"] = component;
          return r =>
          {
              if (component != null)
              {
                  r.ReleaseComponent(component);
              }
          };
       })
  );

Edit: I've updated the solution using ISubDependencyResolver:

public class LoggerResolver : ISubDependencyResolver
{
    private readonly IKernel kernel;

    public LoggerResolver(IKernel kernel)
    {
        this.kernel = kernel;
    }

    public bool CanResolve(CreationContext context,
                           ISubDependencyResolver contextHandlerResolver,
                           ComponentModel model,
                           DependencyModel dependency)
    {
        return dependency.TargetType == typeof (ICommonLog);
    }

    public object Resolve(CreationContext context,
                          ISubDependencyResolver contextHandlerResolver,
                          ComponentModel model,
                          DependencyModel dependency)
    {
        if (CanResolve(context, contextHandlerResolver, model, dependency))
        {
            return kernel.Resolve<ICommonLog>(new {loggerType = model.Implementation});
        }
        return null;
    }
}

Registration:

container.Register(Component.For<ICommonLog>().ImplementedBy(typeof(CommonLog))
    .LifeStyle.Transient);
container.Register(Component.For<IFoo().ImplementedBy(typeof(Foo))
    .LifeStyle.Transient);
container.Kernel.Resolver.AddSubResolver(new LoggerResolver(container.Kernel));

解决方案

You do not need to register CommonLog. Your sub dependency resolver can new one up for you.

container.Register(Component.For<IFoo>().ImplementedBy<Foo>().LifeStyle.Transient);
container.Kernel.Resolver.AddSubResolver(new LoggerResolver(container.Kernel));

public class LoggerResolver : ISubDependencyResolver
{
    ...

    public object Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency)
    {
        //No need to can resolve, Windsor will do this for you

        return new CommonLog(model.Implementation);
    }
}

EDIT Example of a logger provider

container.Register(Component.For<ILoggerProvider>().ImplementedBy<Log4NetLoggerProvider >().LifeStyle.Transient);

public interface ICommonLoggerProvider
{
    ICommonLog GetLogger( Type type );
}

public class Log4NetLoggerProvider : ICommonLoggerProvider
{
    public ICommonLog GetLogger(Type type)
    {
        return new Log4NetLogger(type);
    }
}

public class LoggerResolver : ISubDependencyResolver
{
    ...
    public object Resolve( CreationContext context, ISubDependencyResolver contextHandlerResolver, Castle.Core.ComponentModel model, DependencyModel dependency )
    {
        return kernel.Resolve<ICommonLoggerProvider>().GetLogger( model.Implementation );
    }
}

这篇关于依赖于log4net的记录器,并使用温莎城堡检索记录仪由主叫类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆