18

I have for instance 2 interfases IInterface1 and IInterface2,

public interface IInterface1 {...}
public interface IInterface2 {...} 

and one implementation of these interfaces ImplClass.

public class ImplClass : IInterface1, IInterface2 {...}

I have to be sure that application has only one instance of ImplClass, which will be used as IInterface1 and IInterface2. I'm using ninject for dependency injection. So my qustion is: Does code below will meet my requirements?

...
Bind<IInterface1>().To<ImplClass>().Using<SingletonBehavior>();
Bind<IInterface2>().To<ImplClass>().Using<SingletonBehavior>();
...

Or this code will create 2 instances of ImplClass, for eash interface?

cuongle
  • 74,024
  • 28
  • 151
  • 206
iburlakov
  • 4,164
  • 7
  • 38
  • 40

4 Answers4

20

With Ninject you can do this:

var impl = new Impl();
container.Bind<IInt1>().ToMethod(c => impl);
container.Bind<IInt2>().ToMethod(c => impl);

When the Impl class has dependencies you can't Ninject to inject, you can do this:

container.Bind<Impl>().ToSelf().InSingletonScope();
container.Bind<IInt1>().ToMethod(c => c.Kernel.Get<Impl>());
container.Bind<IInt2>().ToMethod(c => c.Kernel.Get<Impl>()); 

Nice and clean.

Steven
  • 166,672
  • 24
  • 332
  • 435
  • I like it. You don't have to set up the class as an actual singleton, but you guarantee only one instance is ever provided. – KeithS Nov 16 '10 at 15:11
  • -1 Not a good general solution as each resolution leads to an Activation, see http://stackoverflow.com/questions/3043441/prevent-ninject-from-calling-initialize-multiple-times-when-binding-to-several-i – Ruben Bartelink Sep 12 '12 at 08:24
  • 4
    (Better answer until this duplicate question goes away is http://stackoverflow.com/questions/10206049/ninject-is-it-possible-to-bind-different-interfaces-to-the-same-instance-of-a-c ) – Ruben Bartelink Sep 12 '12 at 08:56
  • See Daan's answer below - Ninject v3 now gives you a more elegant way to do this :) – Efrain Mar 21 '16 at 13:56
5

It seems that you're still using Ninject 1.5. I havn't the exact syntax in mind anymore but it should be similat to the following 2.1 syntax:

kernel.Bind<I1>().ToMethod(ctx => ctx.Kernel.Get<Impl>());
kernel.Bind<I2>().ToMethod(ctx => ctx.Kernel.Get<Impl>()); 
kernel.Bind<Impl>().ToSelf().InSingletonScope();

Or even better use Ninject.Extensions.ContextPreservation to keep the context.

kernel.Bind<Impl>().ToSelf().InSingletonScope();
kernel.BindInterfaceToBinding<I1, Impl>();
kernel.BindInterfaceToBinding<I2, Impl>();
Steven
  • 166,672
  • 24
  • 332
  • 435
Remo Gloor
  • 32,665
  • 4
  • 68
  • 98
3

This is how you can do it in one line of code:

Bind<IInterface1 ,IInterface2 ,ImplClass>().To<ImplClass>().InSingletonScope();

https://github.com/ninject/Ninject.Extensions.ContextPreservation/wiki/BindInterfaceToBinding

It requires Ninject version 3.

Daan
  • 2,478
  • 3
  • 36
  • 76
1

I would suspect this would create two instances.

Try whether the following construct works for you:

public class ImplClass : IInterface1, IInterface2
{
    public static readonly ImplClass Instance = new ImplClass();
}

With the following binding:

Bind<IInterface1>().ToMethod(c => ImplClass.Instance);
Bind<IInterface2>().ToMethod(c => ImplClass.Instance);
Pieter van Ginkel
  • 29,160
  • 8
  • 71
  • 111
  • 2
    Good answer, and a +1, but IMO part of the advantage of an IoC framework is that you can set up a singleton object without having to actually define the class structure as a singleton (making it easier to change your mind later, or set up a container or factory-scoped registration in a different environment). What if he simply initialized a class in the Binding class and registered it as a single-instance scope? (I don't know Ninject's capabilities that well, but Autofac would have no problem doing that). – KeithS Nov 16 '10 at 15:09