Search code examples
c#.netloggingdependency-injectionninject

Ninject: Get the instance injected to a parent object


I have a crazy dependency injection case which I'll explain, but first let me show you some code:

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

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

I'm resolving dependencies using Ninject. All of the above are InTransientScope. IBar is provided by a factory method, which uses one of the IFooContext properties for creation. What I want to achieve is to have Service injected into Foo with the same IBar instance that was injected into Foo.

I have no idea how to achieve this with Ninject. Is it even possible? If not, I'm thinking about exposing IBar property in IService and setting it in Foo constructor, but honestly I don't like this idea.

I simplified my case for sake of...simplicity, but in reality Foo is Rebus message handler, IFooContext is a message context, IBar is a logger. I want to format logger messages so that they include ID from a Rebus message being handled. And I want both Foo's and Service's log events to have that ID.


Solution

  • Thanks to Nkosi who pointed me towards right direction, I've managed to get what I wanted:

    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);
    
    

    As I said, in reality Foo is a Rebus message handler. For my example that means, that for every Foo new IFooContext is created and also I have access to current one.

    As for Jan Muncinsky's answer - I didn't test it, but from what I read from Ninject's documentation, it seems that it's also a valid solution for this problem.

    Thank you.