0

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

scorpion35
  • 944
  • 2
  • 12
  • 30

1 Answers1

2

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");
Florent Bunjaku
  • 268
  • 2
  • 7
  • Thanks! But I wouldn't know and can't use what to typecast the resolved object to, like in your `var b = (ClassB)...` example. This part needs to be dynamic, I am hoping. Once I have `b` dynamically resolved from the name of the class, I can run methods on `b` – scorpion35 Apr 13 '23 at 13:21
  • 1
    I typecasted it, but since you mentioned that they all will inherit from ``AbstractBaseClass`` you don't have to, you can just call methods of ``AbstractBaseClass``. – Florent Bunjaku Apr 13 '23 at 13:24
  • 1
    You are right, that will work for me. Thank you! – scorpion35 Apr 13 '23 at 14:19