基于C#Ninject参数的绑定

时间:2016-07-27 16:35:18

标签: c# asp.net dependency-injection ninject ninject-extensions

我正在使用Ninject注入依赖项。 我有以下类结构:

public interface IClass
{
}

public class Class: IClass
{
 public virtual void Method(Object context)
 {
  --------
 }
}   

public class Class1: IClass
{
 public override void Method(Object context)
 {
  --------
 }
}

public class Class2: IClass
{
 public override void Method(Object context)
 {
  --------
 }
}

context包含 - HasBilling,HasPayment属性以及其他更多属性。

使用工厂模式调用

Method()

public interface IClassFactory
    {
        IClass CreateClass();
    }

_classFactory.CreateClass().Method(....)

因此,当参数HasBilling等于true时,我必须调用Method() Class1实现,类似地,如果HasPayment等于true,{{必须调用Method()实现的1}}。

使用Ninject Binding,我尝试了这些绑定,但两个都没有工作:

Class2

试过这个,但没有运气:

Bind<IClass>().To<Class1>().When(x => x.Target.Member.Name.Contains("HasBilling").Equals(true));

根据参数值(Bind<IClass>().To<Class1>().WithMetadata("HasBilling", true); ),有些人可以帮助我根据需要设置哪些绑定来调用Class1Class2方法(Method)。

非常感谢,

谢谢, WH

1 个答案:

答案 0 :(得分:0)

如果您需要context来确定要加载的具体类型,那么您需要将其传递给您的具体类别或工厂。 AFAIK在那里Ninject无法检查你的调用链来说&#34;方法X将被调用,所以我需要使用这些信息来确定使用哪个具体类&#34;。

如果你换工厂,这个问题很简单:

interface IClassFactory
{
   IClass CreateClass(Object context)
}

class ClassFactory : IClassFactory
{
   IClass CreateClass(Object context)
   {
      if (context.HasBilling)
          return new Class1();

       // default case
       return new Class2();
   }
}

然后你将使用:

IClassFactory classFactory; // injected
object context;

classFactory.CreateClass(context).Method();

另一种方法是使用代理模式。 IClass保持不变,取消IClassFactory。而是使用代理:

public class ClassProxy : IClass
{
    void Method(Object context)
    {
       if (context.HasBilling) 
          new Class1().Method(context);
       else
        //etc
    }
}

在你的核心中,你可以将其连接起来:

kernel.Bind<IClass>().To<ClassProxy>();

您还需要确保您的实现未绑定到内核中的IClass。 (因此,请确保不要拥有kernel.Bind<IClass>().To<Class1>()

但是,如果您希望将DI用于实现类,则可以使它们可自我绑定(kernel.Bind<Class1>().ToSelf()),然后您的ClassProxy可以将它们作为依赖项:

class ClassProxy : IClass
{
    private readonly Class1 _class1;    
    private readonly Class2 _class2;

    public ClassProxy(Class1 class1, Class2 class2){
       _class1 = class1;
       _class2 = class2;
    }

    void Method(object context)
    {
         if (context.HasBilling)
             _class1.Method(context);
    }