0

I have a class Consumer which itself requires a certain service IService.

interface IService{...}

class ConcreteService : IService{...}

class Consumer
{
    public Consumer(string someString, IService service)
    {
        //Use service
    }
}

However, in my system I need different instances of the same IService implementation. There are also different consumer instances which require a certain Service instance. Some consumers require MyService1 others require MyService2. To solve this, I created named bindings from IService to ConcreteService. I wired it up like this.

Bind<IService>().To<ConcreteService>().Named("MyService1");
Bind<IService>().To<ConcreteService>().Named("MyService2");

Bind<Consumer>().ToConstructor<Consumer>(c => new Consumer("Consumer1", c.Context.Kernel.Get<IService>("MyService1")));
Bind<Consumer>().ToConstructor<Consumer>(c => new Consumer("Consumer2", c.Context.Kernel.Get<IService>("MyService2")));

Is this the preferred solution to deal with problems like this? I think there are a few alternatives.

First, I could create two different subclasses Consumer1 and Consumer2 and use the [Named(..)] Attribute on the dependency. But I don’t really like the DI framework leaking into my model. Besides this, it could result in a tremendous amount of subclasses.

The other option that I have is creating an additional class ServiceAggregator which gets all bindings for IService injected. The Consumer class could then use the ServiceAggregator to find the appropriate Service. I would use such an approach if the Consumer class required another Service at runtime, but I don’t think it makes much sense if the dependency could be resolved during object instantiation.

class ServiceAggregator
{
    public ServiceAggregator(IService[] services)
    {...}

    public IService GetService(string serviceIdentifier)
    {...}
}

class Consumer
{
    IService myService;

    public Consumer(string someString, string serviceName, ServiceAggregator aggregator)
    {
        myService = aggregator.GetService(serviceName);
    }
}

Is there a way to tell Ninject which dependency to use when there are multiple bindings defined for the same interface?

Bind<Consumer>().To<Consumer().HeyNinjectUse(“MyService1”).IfThereAreMultipleBindingsOf<IService>();

Thanks for your help!

  • Please take a look at NInject [Contextual Bindings](https://github.com/ninject/Ninject/wiki/Contextual-Binding) for tips :) – kayess Jan 29 '16 at 15:34
  • I've read that part before it doesn't seem to cover my problem. I know it has to do something with contextual binding. However, I can't seem to find the right part which solves my problem. – kevin.keller Jan 29 '16 at 16:13
  • So wouldn't `Bind().To().WhenInjectedInto(typeof(Consumer1));` and `Bind().To().WhenInjectedInto(typeof(Consumer2));` fit your need? – kayess Jan 29 '16 at 16:22
  • You're talking about creating two subclasses `ConsumerWhichNeedsService1` and `ConsumerWhichNeedsService2`? This would be okay if consumer is the only class which requires the service. However, there will be much other classes that require that service so the binding would be a huge chain of: WhenInjectedInto(thatClass).WhenInjectedInto(otherClass) etc. I'd rather have my classes or at least their bindings "choose" the apropriate service. – kevin.keller Jan 29 '16 at 16:50
  • Im not sure but that sounds like service locatorish to me... – kayess Jan 29 '16 at 17:16
  • You might want to look into "inherited" parameters and creating a custom `When...` condition which looks for that parameter. Inherited parameter is simply an [`IParameter`](https://github.com/ninject/Ninject/blob/e09664f4c3db5c2d1599cd11dbea6ae28d16f1ff/src/Ninject/Parameters/IParameter.cs) with `ShouldInherit` flag set to `true`. – BatteryBackupUnit Jan 30 '16 at 11:01
  • See [this answer](http://stackoverflow.com/questions/1943576/is-there-a-pattern-for-initializing-objects-created-via-a-di-container/1945023#1945023). Also, have a look at the [strategy pattern](http://stackoverflow.com/questions/31950362/factory-method-with-di-and-ioc#31971691) for an alternate way of achieving the same thing using the strategy pattern combined with abstract factories with varying dependency lists. Or [inject a function into a factory](http://stackoverflow.com/questions/31950362/factory-method-with-di-and-ioc#31956803) and actually use the container to resolve dependencies. – NightOwl888 Jan 30 '16 at 18:36
  • The factory solution is pretty neat if i try to create the dependencies from within my classes. I think it can be easily extended to support singleton scopes for dependencies. If also been somewhat successful at implementing a custom IParameter implementation which resolves the named dependency. – kevin.keller Jan 31 '16 at 10:15

0 Answers0