Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Log4net 将LogManager.GetLogger与Unity一起使用_Log4net_Unity Container - Fatal编程技术网

Log4net 将LogManager.GetLogger与Unity一起使用

Log4net 将LogManager.GetLogger与Unity一起使用,log4net,unity-container,Log4net,Unity Container,鉴于这一类别: class Foo { readonly ILog log; public Foo(ILog log) { this.log = log; } ... } 我想将Unity配置为注入ILog。这很简单: container.RegisterInstance<ILog>(LogManager.GetLogger(typeof(XYZ))); 但是在这种情况下,t是要解析的类型(ILog),而不是对象解析的

鉴于这一类别:

class Foo
{
    readonly ILog log;

    public Foo(ILog log)
    {
        this.log = log;
    } 

    ...
}
我想将Unity配置为注入ILog。这很简单:

container.RegisterInstance<ILog>(LogManager.GetLogger(typeof(XYZ)));
但是在这种情况下,
t
是要解析的类型(
ILog
),而不是对象解析的类型(
Foo

我知道我能做到:

container.RegisterType<Foo>(new InjectionFactory(c => new Foo(LogManager.GetLogger(typeof(Foo)));
container.RegisterType(新注入工厂(c=>newfoo(LogManager.GetLogger(typeof(Foo)));
但我不想每次注册一个对象时都要添加那个疯狂的声明


我知道这可以在Autofac中实现,我知道真正的答案是首先不使用Unity,但这可以实现吗?:)Unity可能无法提供其他容器提供的所有功能,但我还没有找到一个您无法轻松添加的功能。

var container=newunitycontainer();
container.AddNewExtension();
container.RegisterType(
新注入工厂((中心、类型、名称)=>
{
var tracker=ctr.Resolve();
var parentType=tracker.CurrentBuildNode.Parent.BuildKey.Type;
返回LogManager.GetLogger(parentType);
}));
var sut=container.Resolve();
AreEqual(typeof(UsesLog),sut.Log.Type);

您可以找到TrackingExtension的源代码。它位于TecX.Unity项目文件夹中。

如果您希望DI容器根据类的类型信息返回记录器,则将类型信息放入公共接口,以便DI容器可以看到它。这样就不需要任何特定于容器的覆盖然后,无论您使用的是Unity还是AutoFac,这都无关紧要

熟悉log4net对象模型的人可能会为您提供更高效的实现,但请尝试以下方法:

using System;
using Microsoft.Practices.Unity;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace UnityLoging
{
    public interface ILog<T> : log4net.ILog
    { }

    public class MyLogger<T> : log4net.Core.LogImpl, ILog<T>
    {
        public MyLogger() : base(log4net.LogManager.GetLogger(typeof(T).Name).Logger)
        { }
    }

    public class ClassToLog
    {
        private readonly log4net.ILog log;

        public ClassToLog(ILog<ClassToLog> log)
        {
            this.log = log;
        }

        public void LogMe()
        {
            log.Debug("Got here");
        }
    }

    [TestClass]
    public class TestClass
    {
        [TestMethod]
        public void GenericLogRegistrationTest()
        {
            log4net.Config.XmlConfigurator.Configure();
            IUnityContainer container = new UnityContainer();
            container.RegisterType(typeof(ILog<>), typeof(MyLogger<>));

            ClassToLog c = container.Resolve<ClassToLog>();
            c.LogMe();

            log4net.LogManager.Shutdown();
        }
    }
}
使用系统;
使用Microsoft.Practices.Unity;
使用Microsoft.VisualStudio.TestTools.UnitTesting;
命名空间单元化
{
公共接口ILog:log4net.ILog
{ }
公共类MyLogger:log4net.Core.LogImpl,ILog
{
public MyLogger():base(log4net.LogManager.GetLogger(typeof(T).Name).Logger)
{ }
}
公共类类日志
{
私有只读log4net.ILog日志;
公共类日志(ILog日志)
{
this.log=log;
}
公共无效日志()
{
调试(“到达这里”);
}
}
[测试类]
公共类TestClass
{
[测试方法]
公共无效GenericLogRegistrationTest()
{
log4net.Config.XmlConfigurator.Configure();
IUnityContainer容器=新的UnityContainer();
RegisterType(typeof(ILog),typeof(MyLogger));
ClassToLog c=container.Resolve();
c、 LogMe();
log4net.LogManager.Shutdown();
}
}
}

这似乎是一个非常干净的方法:

谢谢,我最终使用了基于相同模型的东西。我发现一件事是我必须实现IRecovery来处理未调用PostBuilding的情况。TrackingStrategy的PostBuilding没有被调用?据我所知,只有在策略声明没有调用的情况下,这才有可能他认为在预构建中构建是完整的(事实并非如此),或者管道中的某个地方存在异常,从而过早地中断了链。没错。我不确定是否存在异常,但我们确实存在一些[可选依赖性]这可能无法加载,因此不需要进行后期构建。有趣的方法。它与容器无关,但有点冗长,开发人员需要知道ILog中的T必须与将记录器作为依赖项的类的类型匹配。
var container = new UnityContainer();
container.AddNewExtension<TrackingExtension>();
container.RegisterType<ILog>(
  new InjectionFactory((ctr, type, name) =>
    {
      var tracker = ctr.Resolve<ITracker>();
      var parentType = tracker.CurrentBuildNode.Parent.BuildKey.Type;
      return LogManager.GetLogger(parentType);
    }));
var sut = container.Resolve<UsesLog>();
Assert.AreEqual(typeof(UsesLog), sut.Log.Type);
using System;
using Microsoft.Practices.Unity;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace UnityLoging
{
    public interface ILog<T> : log4net.ILog
    { }

    public class MyLogger<T> : log4net.Core.LogImpl, ILog<T>
    {
        public MyLogger() : base(log4net.LogManager.GetLogger(typeof(T).Name).Logger)
        { }
    }

    public class ClassToLog
    {
        private readonly log4net.ILog log;

        public ClassToLog(ILog<ClassToLog> log)
        {
            this.log = log;
        }

        public void LogMe()
        {
            log.Debug("Got here");
        }
    }

    [TestClass]
    public class TestClass
    {
        [TestMethod]
        public void GenericLogRegistrationTest()
        {
            log4net.Config.XmlConfigurator.Configure();
            IUnityContainer container = new UnityContainer();
            container.RegisterType(typeof(ILog<>), typeof(MyLogger<>));

            ClassToLog c = container.Resolve<ClassToLog>();
            c.LogMe();

            log4net.LogManager.Shutdown();
        }
    }
}