如何注册和解决Autofac依赖注入框架中的许多类到一个接口
问题描述:
我正在处理产品导入模块(NopCommerce3.9插件),我有100 +不同的导入格式(不同的飞行Excel文件)。与导入方法,所以我已经创建了一个IFormat接口,因此每个新格式类将实现IFormat和进口提供自己的逻辑如何注册和解决Autofac依赖注入框架中的许多类到一个接口
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();
}
}
当导入Action执行时,它会从配置中读取当前格式。并将其传递给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语句。我可以使用反射来做,但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");
}
}
答
Autofac支持命名服务,看看这里:http://docs.autofac.org/en/latest/advanced/keyed-services.html
注册
builder.RegisterType<Format_A>().Named<IFormat>("xls");
解决
var impl = container.ResolveNamed<IFormat>("xls");