Ninject工厂扩展将多个具体类型绑定到一个接口

本文关键字:接口 一个 绑定 扩展 工厂 Ninject 类型 | 更新日期: 2023-09-27 17:55:09

>简介:

我正在使用 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();
      }
}

问题:

我的

工厂按预期注入到我的服务类中,可用于创建汽车对象,但是ninject在这里爆炸,因为它无法正确解析ICar到混凝土类型即。 MercedesFerrari由工厂CreateCar()方法返回。

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

问题:

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

谢谢!

Ninject工厂扩展将多个具体类型绑定到一个接口

在 wiki ninject.extension.factory有一个自定义工厂的例子

首先,创建自定义实现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();
    }
}

CarModule指定ICarFactory工厂的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:这是完整示例

相关文章: