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

1.1k views Asked by At

i'm working on product import module(NopCommerce3.9 plugin), i have 100+ different import format (excel file with different flied). so I've created one IFormat interface with import method so each new format class will implement the IFormat and provide their own logic for import

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
}

I've registered formats type/class on autofac as below

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

When import Action execute, it will read current format from config. and pass it to FormatFactory.GetFormat() method.

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

the FormatFactory will resolve/create new object base on format parameter passed. using Autofac dependency framework

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

Now, is there any way to remove switch statement from Factory. I could do it using reflection but the Format classes have other dependencies(in actual code). so, is there any way to achieve this in Autofac, likewise i can resolve type by string name of class. i want something like below code

 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

There are 1 answers

0
mbnx On BEST ANSWER

Autofac supports named services, take a look here: http://docs.autofac.org/en/latest/advanced/keyed-services.html

Registration

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

Resolving

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