Ninject正在重用在InTransientScope()中明确定义的实例

时间:2018-10-18 13:45:36

标签: asp.net-mvc ninject log4net

我遇到了一个问题,并且在如何调试和解决此问题上已陷入僵局。

我有一个MVC应用程序,该应用程序使用Ninject进行IoC和DI。

我的依赖项之一是IApplicationLogger,我目前正在使用Log4Net来实现。

在我的NinjectWebCommon中,我按以下方式绑定我的IApplicationLogger:

kernel.Bind<IApplicationLogger>()
    .ToMethod(ctx =>
    {
        string configFile = System.Configuration.ConfigurationManager.AppSettings["log4netconfigfilelocation"];
        log4net.Config.XmlConfigurator.Configure(new System.IO.FileInfo(HttpContext.Current.Server.MapPath(configFile)));

        var name = ctx.Request.Target.Member.DeclaringType.FullName;

        var log4Netlogger = log4net.LogManager.GetLogger(name);
        return new Log4NetApplicationLogger(log4Netlogger);
    }).InTransientScope();

所有相当简单的东西。

但是,我发现被激活的IApplicationLogger的第一个实例随后被传递给所有需要IApplicationLogger实例的构造函数。

例如,我有以下内容

 public class A : IA
 {
        public A(IB bclass, IC cclass, IApplicationLogger logger){}
    }

public class B : IB
{
    public B(IApplicationLogger logger){}
}

public class C : IC
{
    public C(IApplicationLogger logger){}
}

我在每个构造函数上以及在NinjectWebCommon kernel.Bind()。ToMethod(ctx =>

这是我看到的:

  • NinjectWebCommon中的断裂点被击中,我可以看到 ctx.Request.Target.Member.DeclaringType.FullName是B类。
  • 构造器B类的断裂点被击中并记录 实例是正确的
  • 构造器类C中的断裂点被击中,并且 记录器实例的记录器名称为B类
  • 构造器类A中的断裂点被击中,并且记录器实例具有记录器 B类的名称

我希望在NinjectWebCommon中的断点在所需的每个IApplicationLogger新实例时都被命中,但是对于第一次激活B类实例,只被命中一次。

我尝试了不带InTransientScope()选项的绑定。

我的IA,IB和IC绑定在InSingletonScope()中定义。这应该不会引起问题,因为我希望Ninject激活每个实例,每个实例都具有自己的IApplicationLogger实例。

我目前看到的绑定结果是,我在说A类中输出的日志记录语句记录为来自B类类的记录器名称。

任何人都可以建议我如何诊断Ninject为什么重用TransientScoped()IApplicationLogger,或者如何窥探Ninject所做的事情,以便我可以对此进行更详细的分析?

1 个答案:

答案 0 :(得分:0)

对于感兴趣的人,我没有在这里发现潜在的问题,但是我选择使用单个方法.GetLogger(string typename)注入ILoggerFactory,允许我的类请求自己的Logger并传递自己的Type名称。

这样,我可以确保每个类都有自己的记录器,并且LoggerName与Class TypeName相匹配。