Как зарегистрировать и разрешить множество классов для одного интерфейса в Autofac Dependency инъекция Framework

Я работаю над модулем импорта продукта (плагин NopCommerce3.9), у меня более 100 различных форматов импорта (файл Excel с разными полями). поэтому я создал один интерфейс IFormat с методом импорта, чтобы каждый новый класс формата реализовывал IFormat и предоставлял собственную логику для импорта.

interface IFormat
{
     bool Import(file)
}

class Format_A : IFormat
{
 public bool Import(file)
    //import with A format
}

class Format_B : IFormat
{
 public bool Import(file)
    //import with B format
}

Я зарегистрировал форматы типа / класса на autofac как ниже

public class DependencyRegistrar
{
    public virtual void Register(Autofac_Container builder)
    {
          builder.RegisterType<Format_A>().AsSelf().InstancePerLifetimeScope();
          builder.RegisterType<Format_B>().AsSelf().InstancePerLifetimeScope();
    }
}

Когда действие импорта выполнено, он будет читать текущий формат из конфигурации. и передать его в метод FormatFactory.GetFormat().

public ActionResult ImportExcel()
{
     var format=format_from_config;
     var file = Request.InputStream;
     IFormat currentFormat = FormatFactory.GetFormat(format);
     bool success = currentFormat.Import(file);
     return Json(new { success = success });
}

FormatFactory разрешит / создаст новую базу объектов на основе переданного параметра формата. используя Autofac каркас зависимостей

class FormatFactory 
{
    public static IFormat GetFormat(string format)
    {
        switch (format)
        {
            case "Format_A":
                return Autofac_Container.Resolve<Format_A>();
            case "Format_B":
                return Autofac_Container.Resolve<Format_B>();
            default:
                throw new ArgumentException($"No Type of {nameof(format)} found by factory", format);
        }
    }
}

Теперь есть ли способ удалить оператор switch из Factory. Я мог бы сделать это с помощью отражения, но у классов Format есть и другие зависимости (в реальном коде). Итак, есть ли способ достичь этого в Autofac, также я могу разрешить тип по строковому имени класса. я хочу что-то вроде кода ниже

 public class DependencyRegistrar
    {
        public virtual void Register(Autofac_Container builder)
        {
              builder.RegisterType<Format_A>().As<IFormat>().Resolve_If_String_Name_like("Format_A").InstancePerLifetimeScope();
              builder.RegisterType<Format_B>().As<IFormat>()Resolve_If_String_Name_like("Format_B").InstancePerLifetimeScope();
        }
    }
-------------------------------------------------------------------
class FormatFactory 
{
   public static IFormat GetFormat(string format)
   {
      return Autofac_Container.Resolve<IFormat>("Format_A");
   }
}

1 ответ

Решение

Autofac поддерживает именованные сервисы, посмотрите здесь: http://docs.autofac.org/en/latest/advanced/keyed-services.html

Постановка на учет

builder.RegisterType<Format_A>().Named<IFormat>("xls");

Разрешающая

var impl = container.ResolveNamed<IFormat>("xls");
Другие вопросы по тегам