Расширение Ninject Factory связывает несколько конкретных типов с одним интерфейсом

Вступление:

Я использую 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;
    }
 }

Затем используйте метод фабричного расширения "ToFactory" для привязки интерфейса моего автомобильного завода:

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

Проблема:

Моя фабрика впрыскивается в мой класс обслуживания, как и ожидалось, и может использоваться для создания автомобильных объектов, однако здесь происходит взрыв, потому что он не может правильно разрешить ICar для конкретного типа, т.е. Mercedes или же Ferrari вернулся на завод CreateCar() метод.

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

Вопрос:

Предполагая, что используемый здесь фабричный шаблон совместим с тем, как предполагается использовать фабричное расширение ninject, как настроить привязки для ICar -> Ferrari, ICar -> Mercedes и т. Д., Чтобы они могли динамически разрешаться во время выполнения с помощью этот подход?

Спасибо!

1 ответ

Решение

Есть пример нестандартной фабрики на 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 уточнить UseFirstArgumentAsNameInstanceProvider (поставщик нестандартного экземпляра) для ICarFactory фабрика и имена для зависимостей

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: вот полный пример

Другие вопросы по тегам