Search code examples
c#autofac

C#/Autofac - Register ALL classes under a directory, and resolve using their string names


Found this - Autofac register and resolve with Names, but I need it to be more dynamic

I have a library, where a lot of new classes will be added. Let's call them NewClass1, NewClass2, etc., and all these classes inherit AbstractBaseClass abstract class.

builder.RegisterAssemblyTypes(libraryAssembly)
            .Where(t => t.IsSubclassOf(typeof(AbstractBaseClass)));

I am able to resolve NewClass1/2/3/... like this

container.Resolve<NewClass1>()

but I need to specify the class name myself, and it cannot be a string name of the class.

Any pointers anyone? I am looking for something like,

container.Resolve("NewClass1")

// or

container.Resolve("NewClass2")

TIA


Solution

  • You can try something as below:

    var containerBuilder = new ContainerBuilder();
    
    containerBuilder
        .RegisterAssemblyTypes(Assembly.GetCallingAssembly())
        .Where(x => x.IsSubclassOf(typeof(ClassA)))
        .Named<ClassA>(t => t.Name);
    
    var container = containerBuilder.Build();
    
    var b = (ClassB)container.ResolveNamed<ClassA>("ClassB");
    var c = (ClassC)container.ResolveNamed<ClassA>("ClassC");
        
    

    You can take it further and create a factory like this:

    containerBuilder
        .Register((context, parameters) =>
        {
            var name = parameters.TypedAs<string>();
            if (context.TryResolveNamed<ClassA>(name, out var service)) return service;
            throw new InvalidOperationException();
        })
        .As<ClassA>();
    
    ... 
    
    var factory = container.Resolve<Func<string, ClassA>>();
    
    var b = (ClassB)factory("ClassB");
    var c = (ClassC)factory("ClassC");