首页 文章

Ninject Factory Extension将多种混凝土类型绑定到一个界面

提问于
浏览
10

简介:

我正在使用Ninject Factory Extension将简单的对象工厂注入我的服务类 .

这是我的界面和两个实现它的类:

public interface ICar
{
    void Drive();
    void Stop();
}

public class Mercedes : ICar
{
    public void Drive()
    {
      Do mercedes drive stuff...
    }

    public void Stop()
    {
      Do mercedes stop stuff...  
    }

}

public class Ferrari : ICar
{
    public void Drive()
    {
      Do ferrari drive stuff...
    }

    public void Stop()
    {
      Do ferrari stop stuff...  
    }
}

这是我在运行时动态创建汽车的对象工厂:

public interface ICarFactory
{
   ICar CreateCar(string carType);
}

public class CarFactory : ICarFactory 
{
   public ICar CreateCar(string carType)
   {
       ICar car;

       switch (type)
       {
           case "mercedes":
                car = new Mercedes();
           break;

           case "ferrari":
               car = new Ferrari();
           break;
       }

       return car;
    }
 }

然后使用ninject工厂扩展“ToFactory”方法绑定我的汽车工厂界面:

public class CarModule : Ninject.Modules.NinjectModule
{
      public override void Load()
      {
           Bind<ICarFactory>().ToFactory();
      }
}

问题:

我的工厂按预期注入我的服务类,可用于创建汽车对象,但是因为无法将ICar正确地解析为具体类型,因此ninject在这里爆炸 . MercedesFerrari 由工厂 CreateCar() 方法返回 .

public CarService(string carType, ICarFactory carFactory)
{
   var car = carFactory.CreateCar(carType);
}

问题:

假设我在这里使用的工厂模式与ninject工厂扩展的工作方式兼容,我如何设置ICar的绑定 - >法拉利,ICar - > Mercedes等,以便它们可以在运行时动态解析这种方法?

谢谢!

1 回答

  • 23

    ninject.extension.factory wiki有一个定制工厂的例子

    首先,创建 StandardInstanceProvider 的自定义实现以覆盖默认的工厂行为

    public class UseFirstArgumentAsNameInstanceProvider : StandardInstanceProvider
    {
        protected override string GetName(System.Reflection.MethodInfo methodInfo, object[] arguments)
        {
            return (string)arguments[0];
        }
    
        protected override ConstructorArgument[] GetConstructorArguments(MethodInfo methodInfo, object[] arguments)
        {
            return base.GetConstructorArguments(methodInfo, arguments).Skip(1).ToArray();
        }
    }
    

    CarModuleICarFactory factory指定 UseFirstArgumentAsNameInstanceProvider (自定义实例提供程序),为依赖项指定名称

    public class CarModule : NinjectModule
    {
        public override void Load()
        {
            Bind<ICarFactory>()
                .ToFactory(() => new UseFirstArgumentAsNameInstanceProvider());
    
            Bind<ICar>()
                .To<Mercedes>()
                .Named("Mercedes");
    
            Bind<ICar>()
                .To<Ferrari>()
                .Named("Ferrari");
        }
    }
    

    解决工厂和依赖项

    var factory = kernel.Get<ICarFactory>();
    
    var mercedes = factory.CreateCar("Mercedes");
    var ferrari = factory.CreateCar("Ferrari");
    

    ps :这里是full example

相关问题