【问题标题】:Is there a way to Resolve log4net using Unity without calling ILog in the constructor?有没有办法使用 Unity 解决 log4net 而无需在构造函数中调用 ILog?
【发布时间】:2018-02-15 12:52:38
【问题描述】:

所以我通常这样做(使用 DI)的方式是将扩展添加到我的容器中:

unityContainer.AddNewExtension<Log4NetExtension>();

然后在我需要调用记录器的类的构造函数中,我使用如下内容:

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

现在我的问题是,在我的一个类中,我不想将任何东西传递给构造函数,我想知道如何分配我的记录器(因为我使用统一我想调用 resolve,但它不起作用)

public class test
{
    private ILog logger;

    public test()
    {
        logger = unityContainer.Resolve<ILog>(); //I edited this for simplicity
    }
}

错误是容器不知道如何解析 ILog。

编辑:

不允许我通过其构造函数传递任何内容的类是 Job(实现 IJob)类,最后我最终使用了作业侦听器而不是登录每个作业。

如果您仍想为构造函数传递一些东西,一些提示是通过实现 Job Factory 来帮助您注入参数。我看到了一个 nuget,您可以添加以帮助您使用 Quartz integration with Unity

【问题讨论】:

  • 您检查过注册和解析的顺序吗? unityContainerDIContainer.Container 是否引用了同一个 UnityContainer 实例?
  • @stukselbax 是的,我的错我应该提到我的 DIContainer 有一个 Container 字段,它是 unitycontainer 所以它是一样的。
  • Log4NetExtension 长什么样子?你能提供重现你的问题的代码吗?
  • Log4NetExtension 是 Unity 的一个内置扩展,它通常像我的第一个示例一样工作(我通过构造函数传递它)

标签: c# asp.net-web-api unity-container log4net


【解决方案1】:

Log4net 允许您使用类中的名称创建记录器,无需通过构造函数传递它。

将此添加为类成员

私有静态只读 log4net.ILog logger = log4net.LogManager.GetLogger("MyAppLog");

当然,这不会使用您的 DIContainer。

【讨论】:

  • 没错,按照你的方式做肯定会奏效,但我想使用 DI 来做,所以我不会在每个课程中都使用相同的东西。
【解决方案2】:

你可以使用属性注入:

public class test
{
    [Dependency]
    public ILog Logger { get; set; }

    public test()
    {
    }
}

不过有两个缺点:

  1. 记录器现在是公共可写属性,因此任何人都可以在技术上使用或覆盖您的记录器
  2. 属性注入用于可选依赖项,因此您可能会混淆查看该类的其他人

【讨论】:

  • 啊,谢谢你提到这一点,我会记住的!但就我个人而言,我最终还是没有在该课程中使用记录器。
猜你喜欢
  • 2021-11-11
  • 1970-01-01
  • 2019-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-11
  • 1970-01-01
相关资源
最近更新 更多