Как зарегистрировать и разрешить множество классов для одного интерфейса в 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");