【问题标题】:How to Inject Log4Net ILog implementations using Unity 2.0如何使用 Unity 2.0 注入 Log4Net ILog 实现
【发布时间】:2011-07-27 14:46:07
【问题描述】:

这最终与设置 log4Net 有关,但通常问题不是特定于日志记录。

一般来说,我想弄清楚的是如何在 Microsoft Unity 2.0 中做一些与 Castle.Facilities.Logging.LoggingFacility 相同的事情。即能够声明对记录器的依赖关系并使用要注入的对象的类型来初始化记录器。

一试千言万语,这就是我所需要的:

class Logger_IOC_Tests
{
    //[Test] 
    public void Logger_should_be_initialized_with_the_type_of_the_object_that_is_using_it()
    {
        var container = new UnityContainer();
        /* Configuration Magic probably involiving registering either 
            * a custom IDependencyResolverPolicy or BuilderStrategy
            * goes here...
            */
        container.RegisterType<LoggerUser>(new ContainerControlledLifetimeManager());

        var user = container.Resolve<LoggerUser>();

        Assert.True(user.Logger.GetUserType() == user.GetType());
    }
}

interface ILogger
{
    Type GetUserType();
}

class Logger : ILogger
{
    private readonly Type _type;

    public Logger(Type type)
    {
        _type = type;
    }

    public Type GetUserType()
    {
        return _type;
    }
}

class LoggerUser
{
    public readonly ILogger Logger;

    public LoggerUser(ILogger logger)
    {
        Logger = logger;
    }
}

【问题讨论】:

    标签: c# dependency-injection unity-container log4net castle-windsor


    【解决方案1】:

    我不知道这是否是您要查找的内容,但几个月前我看到了它,并在看到您的问题时想起了它。我没有使用 Unity,所以我无法将您发布的内容与链接中的内容进行比较。希望对您有用:

    http://davidkeaveny.blogspot.com/2011/03/unity-and-log4net.html

    【讨论】:

    • 你这次是头上的锤子。正是我正在寻找的,比我的解决方案要好得多。非常感谢。
    • 为了它的价值,我将论坛和大卫博客中的代码放在一起,并将它们放在我博客上here 的一个地方。
    • Unity.codeplex 讨论中有更高的抽象级别可用LogCreation&lt;T,U&gt; : UnityContainerExtension where U : ILogFactory, new()。它将 LogCreation 与日志框架分离。因此可以对 NLog 使用相同的方法,例如唯一的一件事是为某些日志框架实现 LogFactory。我在github 合并了源代码
    【解决方案2】:

    我一直在尝试使用 Unity 的构造函数注入将正确配置的 ILog 实例插入到依赖项中来实现相同的结果。

    最后,我编写了自己的“log4net”统一扩展来完成此任务(部分灵感来自另一位回答者 Kenneth Baltrinic 所写的博客文章)。

    这允许您在 Unity 中注册一次扩展:

    var container = new UnityContainer();
    container.AddNewExtension<Log4NetExtension>();
    

    然后传入正确的 ILog 记录器实例:

    public class MyClass
    {
        private readonly ILog logger;
    
        public MyClass(ILog logger)
        {
            this.logger = logger;
        }
    }
    

    扩展可以在这里找到:

    https://github.com/roblevine/UnityLoggingExtensions

    更多信息在这里:http://blog.roblevine.co.uk/net/using-log4net-with-unity/

    EDIT现在可以使用NuGet package

    【讨论】:

    • 我这辈子都无法在我的应用程序中读取 web.config log4net 配置。我确实尝试在 AssemblyInfo.cs 和 Global.asax 中添加 [assembly: log4net.Config.XmlConfigurator(Watch = true)] 行。我做错了什么?
    • @Harindaka 注册类型并添加扩展后,添加行“log4net.Config.XmlConfigurator.Configure();”这将根据您的配置文件进行配置。
    • 是的,这就是我所做的。但我想知道为什么正常的 [assembly: log4net.Config.XmlConfigurator(Watch = true)] 方法在这种情况下不起作用。我觉得我通过调用 log4net.Config.XmlConfigurator.Configure() 来强制 log4net。 :D
    • 嗯 - 这很奇怪 - 他们都应该这样做。
    【解决方案3】:

    在对 Unity 源代码进行了数小时的研究之后,我想出了以下解决方案。但是,我更愿意找到一种方法来根据要解析的类型设置适当的依赖解析器,而不是覆盖默认的构造函数选择器策略。一方面,因为我之前出于其他目的覆盖了默认构造函数选择器。另一方面,此解决方案仅处理通过构造函数注入的依赖项。为了全面覆盖,我认为也必须覆盖默认的属性和方法选择器。对于我自己,我只需要构造函数。

    class Logger_IOC_Tests
    {
        [Test] 
        public void Logger_should_be_initialized_with_the_type_of_the_object_that_is_using_it()
        {
            var container = new UnityContainer();
            container.AddNewExtension<LoggingExtension>();
            container.RegisterType<LoggerUser>(new ContainerControlledLifetimeManager());
            var user = container.Resolve<LoggerUser>();
    
            Assert.True(user.Logger.GetUserType() == user.GetType());
        }
    }
    
    class LoggingExtension : UnityContainerExtension
    {
        protected override void Initialize()
        {
            Context.Policies.SetDefault(typeof(IConstructorSelectorPolicy), new LoggingConstructorSelectorPolicy()); 
        }
    }
    
    public class LoggingConstructorSelectorPolicy : DefaultUnityConstructorSelectorPolicy
    {
        protected override IDependencyResolverPolicy CreateResolver(ParameterInfo parameter)
        {
            return parameter.ParameterType == typeof(ILogger) 
                       ? new LoggerResolverPolicy(parameter.Member.DeclaringType) 
                       : base.CreateResolver(parameter);
        }
    }
    
    class LoggerResolverPolicy : IDependencyResolverPolicy
    {
        private readonly Type _dependantType;
    
        public LoggerResolverPolicy(Type dependantType)
        {
            _dependantType = dependantType;
        }
    
        public object Resolve(IBuilderContext context)
        {
            return new Logger(_dependantType);
        }
    }
    

    【讨论】:

      【解决方案4】:

      上述扩展运行良好,但 MVC5 用户需要更多配置信息。以下是使用 unity 的步骤。

      将以下行添加到命名空间上方的 startup.cs 类的顶部。

      [程序集:log4net.Config.XmlConfigurator(ConfigFile="Web.config", Watch = true)]

      在您的 global.asax application_startup 方法中添加以下信息:

      log4net.Config.XmlConfigurator.Configure(new FileInfo(Server.MapPath("~/Web.config")));
      

      统一容器的其余配置应保持原样:

      container.AddNewExtension<Log4NetExtension>();
      

      确保您已将 appender 添加到您的 web.config。这应该是为了让它正常工作。祝你好运

      【讨论】:

        【解决方案5】:

        使用 Unity 5 及更高版本,您现在可以使用来自 https://github.com/unitycontainer/log4net 的 Unity 自己的 Log4Net 扩展。

        您所要做的就是安装 Nuget 并将扩展添加到您的容器中:

        container.AddNewExtension<Log4NetExtension>();
        

        它会自动与任何使用ILog 作为依赖项的类一起工作。

        【讨论】:

          【解决方案6】:

          可以使用以下代码注入Log4Net

          log4net.Config.BasicConfigurator.Configure();    
          
          container.RegisterType<ILog>(new InjectionFactory(x => LogManager.GetLogger(typeof(Program))));
          

          typeof(Program) 因为我在程序类中注册而被使用。使用可以使用类名或this关键字

          然后你可以将 ILog 注入到类中

           public class MyClass
           {
             private readonly ILog logger;
          
             public MyClass(ILog logger)
             {
               this.logger = logger;
             }
           }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-11-18
            相关资源
            最近更新 更多