Ninject повторно использует экземпляры, которые явно определены InTransientScope () - PullRequest
0 голосов
/ 18 октября 2018

У меня возникла проблема, и я зашел в тупик на пути отладки и устранения этой проблемы.

У меня есть приложение 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. Bind (). ToMethod (ctx =>

Что я вижу, это:

  • Точка останова в NinjectWebCommonударил, и я вижу, ctx.Request.Target.Member.DeclaringType.FullName является класс B.
  • Точка останова в конструкторе класса B ударил и лЭкземпляр ogger правильный
  • Достигнута точка останова в конструкторе класса C, а у экземпляра регистратора есть имя регистратора Типа класса B
  • Достигнута точка останова в классе конструктора A, а у экземпляра регистратора естьимя регистратора класса B

Я ожидаю, что точка останова в NinjectWebCommon будет достигнута для каждого необходимого нового экземпляра IApplicationLogger, но он ударится только один раз для первой активации для экземпляра класса B.

Я попробовал свою привязку без опции InTransientScope ().

Мои привязки IA, IB и IC определены InSingletonScope ().Это не должно вызывать проблем, так как я ожидаю, что Ninject активирует экземпляр каждого из них, каждый со своим собственным экземпляром IApplicationLogger.

Результат привязки, которую я вижу в настоящее время, заключается в том, что операторы журналирования, которые я выводю в, скажем,Класс A записывается в журнал как имя регистратора для класса типа B.

Может кто-нибудь подсказать, как я могу диагностировать, почему Ninject повторно использует TransientScoped () IApplicationLogger или как я могу просмотреть подЧто делает Ninject, чтобы я мог проанализировать это более подробно?

1 Ответ

0 голосов
/ 19 октября 2018

Для всех, кого это интересует, я не обнаружил основную проблему здесь, но я решил внедрить ILoggerFactory с помощью одного метода .GetLogger (string typename), позволяя моим классам запрашивать их собственный Logger и передавая их собственное имя типа.

Таким образом, я могу убедиться, что у каждого класса есть свой собственный регистратор с именем LoggerName, совпадающим с именем TypeName класса.

...