Ninject: получить экземпляр, внедренный в родительский объект - PullRequest
1 голос
/ 04 июля 2019

У меня есть сумасшедший случай внедрения зависимостей, который я объясню, но сначала позвольте мне показать вам некоторый код:

  class Foo : IFoo
  {
    Foo(
      IBar bar,
      IFooContext context,
      IService service)
    {
      ...
    }
  }

  class Service : IService
  {
    Service(
      IBar bar)
    {
      ...
    }
  }

Я разрешаю зависимости с помощью Ninject. Все вышеперечисленное InTransientScope. IBar предоставляется фабричным методом, который использует одно из IFooContext свойств для создания. Я хочу добиться, чтобы Service был введен в Foo с тем же экземпляром IBar, который был введен в Foo.

Я понятия не имею, как этого добиться с помощью Ninject. Это вообще возможно? Если нет, я подумываю раскрыть свойство IBar в IService и установить его в конструкторе Foo, но, честно говоря, мне не нравится эта идея.

Я упростил свой случай ради ... простоты, но на самом деле Foo - это обработчик сообщений Rebus, IFooContext - это контекст сообщения, IBar - это регистратор. Я хочу отформатировать сообщения регистратора, чтобы они включали идентификатор из обрабатываемого сообщения Rebus. И я хочу, чтобы события журнала Foo и Service имели этот идентификатор.

Ответы [ 2 ]

1 голос
/ 08 июля 2019

Благодаря Нкоси , который указал мне правильное направление, мне удалось получить то, что я хотел:

Bind<IFoo>()
  .To<Foo>
  .InScope(ctx => FooContext.Current);

Bind<IBar>()
  .ToMethod(ctx =>
  {
    var scope = ctx.GetScope() as IFooContext;
    // Some logic to create Bar by IFooContext...
  });

Bind<IService>()
  .To<Service>
  .InScope(ctx => FooContext.Current);

Как я уже сказал, на самом деле Foo - это обработчик сообщений Rebus. Для моего примера это означает, что для каждого Foo создается новый IFooContext, а также у меня есть доступ к текущему.

Что касается ответа Jan Muncinsky - я не проверял его, но из того, что я прочитал из документации Ninject, кажется, что это также правильное решение этой проблемы.

Спасибо.

1 голос
/ 06 июля 2019

Это можно решить с помощью Ninject.Extensions.NamedScope

kernel.Bind<IFoo>().To<Foo>().DefinesNamedScope("FooScope");
kernel.Bind<IBar>().To<Bar>().InNamedScope("FooScope");
...