C#基于参数的绑定

本文关键字:绑定 参数 于参数 | 更新日期: 2023-09-27 17:59:06

我正在使用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时,我必须调用Class1实现的Method(),类似地,如果HasPayment等于true,则必须调用Class2实现的Method()

使用NinjectBinding,我尝试了这些绑定,但都不起作用:

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

尝试过这个,但没有运气:

Bind<IClass>().To<Class1>().WithMetadata("HasBilling", true);

请有人帮助我根据参数值(HasBilling,HasPayment)调用Class1Class2方法(Method)需要设置哪些绑定。

非常感谢,

谢谢,WH

C#基于参数的绑定

如果需要context来确定要加载的混凝土类型,则需要将其传递给混凝土类或工厂。AFAIK对于Ninject来说,没有办法检查您的调用链来说"方法X将被调用,所以我需要使用这些信息来确定要使用哪个具体类"。

如果你更换你的工厂,这个问题因为很简单:

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);
    }