Search code examples
c#dependency-injectionninjectinversion-of-controlioc-container

Can we combine two bindings with different condition?


First for types inferences types which have attribute

 var _kernel1 = new StandardKernel();

Second -- which not marked with attribute

 var_kernel2 = new StandardKernel();

It should be like , if we cannot resolve type in first kernel1, resolve it in second kernel2

Bindings:

  _kernel1.Bind(a =>
  {
      a.FromThisAssembly()
     .SelectAllClasses()
     .InheritedFrom<IStepContext>().WithAttribute<MarkAttribute>(x => x.Type == Inheritance.Derived)
     .BindSelection(
           (t, baseTypes) => baseTypes.Where(bt => bt.IsInterface || bt == t.BaseType));
  });

  _kernel2.Bind(a =>
  {
      a.FromThisAssembly()
      .SelectAllClasses().BindAllInterfaces();
  });

Example: (and this kind of classes can be a lot)

public interface IStepContext
{
    Type WhoIAm();
}

public interface IStepContextAB : IStepContextSecond { }

public interface IStepContextSecond : IStepContext { }

abstract class A : IStepContext { }

class B : A { }

class B1 : A { }

[markAttribute]
class B2 : A { }

class C : IStepContextAB { }

class C1 : IStepContextAB { }

[markAttribute]
class C2 : IStepContextAB { }

class D : IStepContext { }

class D1 :D { }

class D2 : D { }

_kernel.Get<B>() ==> B2
_kernel.Get<IStepContextAB>() ==> C2
_kernel.Get<D>() ==> D

Solution

  • It should be like , if we cannot resolve type in first kernel1, resolve it in second kernel2

    I believe in this question what you are looking for is the Ninject ChildKernel extension:

    This Ninject extension allows that child kernels can be defined. A child kernel is a Ninject kernel that has a parent kernel. All requests that it can't resolve are passed to the parent kernel.

    however, it seems what you are trying to get at is conditional bindings:

    Bind<IWarrior>().To<Ninja>();
    Bind<IWarrior>().To<Samurai>().WhenClassHas<ClimberNeeded>();
    Bind<IWarrior>().To<Samurai>().WhenTargetHas<ClimberNeeded>();
    Bind<IWarrior>().To<SpecialNinja>().WhenMemberHas<SwimmerNeeded>();