如何在 Autofac 依赖注入框架中注册和解析多个 class 到一个接口

How to register and resolve many class to one interface in Autofac Dependency injection Framework

我正在开发产品导入模块(NopCommerce3.9 插件),我有 100 多种不同的导入格式(excel 文件格式不同)。所以我创建了一个带有导入方法的 IFormat 接口,这样每个新格式 class 都将实现 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 上注册了格式 type/class,如下所示

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

执行import Action时,会从config中读取当前格式。并将其传递给 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 将 resolve/create 基于传递的格式参数的新对象。 使用 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);
        }
    }
}

现在,有什么方法可以从 Factory 中删除 switch 语句。我可以使用反射来做到这一点,但是 Format classes 有其他依赖项(在实际代码中)。那么,有什么方法可以在 Autofac 中实现这一点,同样我可以通过 class 的字符串名称解析类型。 我想要类似下面的代码

 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");
   }
}

A​​utofac 支持命名服务,看这里:http://docs.autofac.org/en/latest/advanced/keyed-services.html

注册

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

正在解决

var impl = container.ResolveNamed<IFormat>("xls");