Search code examples
c#bindingninjectninject-extensionscontextual-binding

Ninject binding based on object's property? Convention or contextual binding?


I have an interface:

public interface IInterface
{
string Get(obj o);
}

and I have the 2 classes:

public class C1 : IInterface
{
string Get(obj o);
}

public class C2 : IInterface
{
string Get(obj o);
}

I'd like to send in o and then have Ninject determine which interface it is based on the property of o. Obj being something like:

public class obj
{
    public string Name {get;set;}
    public int Id {get;set;}
}

I'd like something that's like:

Bind<IInterface>().To<C1>.When(obj.Name == "C1");
Bind<IInterface>().To<C2>.When(obj.Name == "C2");

but I haven't worked with Ninject before. Any ideas?


Solution

  • I've been somewhat liberal with the interpretation of your question, because i think you've skipped some "thinking steps" and necessary information.

    However, what I recommend is doing it like this:

    public interface INamed
    {
        string Name { get; }
    }
    
    public interface IFactory
    {
        IInterface Create(INamed obj);
    }
    
    public class Factory : IFactory
    {
        private readonly IResolutionRoot resolutionRoot;
    
        public Factory(IResolutionRoot resolutionRoot)
        {
            this.resolutionRoot = resolutionRoot;
        }
    
        public IInterface Create(INamed obj) 
        {
            return this.resolutionRoot.Get<IInterface>(obj.Name);
        }
    }
    

    Alternative: you could also use the ninject factory extension. Sadly enough it does not support named bindings by default, but you can customize it do so like documented here.

    However to be perfectly frank i would rather go for manually implementing the factory, because it is more easily understandable. If i would be customizing the factory - which i have done - i would consider adding support for attributes (which specify how to handle a factory method parameter) instead of having to configure each .ToFactory() binding how it will interpret parameters.