Autofac Scanning Assemblies for certain class type

16,027

Solution 1

I think you need to specify the base class of your Plugins on registration. The call AsImplementedInterfaces registers the type with its implemented interfaces and not by its base type. You should update your registration to register your plugins as PluginBase.

Here´s the code:

var assemblies = AppDomain.CurrentDomain.GetAssemblies();


    var builder = new ContainerBuilder();
    builder.RegisterAssemblyTypes(assemblies)
        .Where(t => t.BaseType == typeof(PluginBase))
        .As<PluginBase>();

    var container = builder.Build();
    var pluginClasses = container.Resolve<IEnumerable<PluginBase>>();

Solution 2

Maybe do is this way:

builder
    .RegisterAssemblyTypes(AppDomain.CurrentDomain.GetAssemblies())
    .Where(t => t.GetInterfaces()
        .Any(i => i.IsAssignableFrom(typeof (IDependency))))
    .AsImplementedInterfaces()
    .InstancePerDependency();

In this code I use IDependency as a marker interface. You may replace it with your PluginBase class and remove Where method.

The point is to use IsAssignableFrom method.

Share:
16,027

Related videos on Youtube

Jon
Author by

Jon

Updated on June 04, 2022

Comments

  • Jon
    Jon almost 2 years

    I've started using Autofac and want to scan some DLL's and get Autofac to register some of the classes within them.

    The classes that I'm interested in all inherit from a PluginBase class but the below code doesn't seem to be registering them. Can anyone help?

            var assemblies = AppDomain.CurrentDomain.GetAssemblies();
    
    
            var builder = new ContainerBuilder();
            builder.RegisterAssemblyTypes(assemblies)
                .Where(t => t.BaseType == typeof(PluginBase))
                .AsImplementedInterfaces()
                .AsSelf();
    
            var container = builder.Build();
            var pluginClasses = container.Resolve<IEnumerable<PluginBase>>();
    
            //pluginClasses is empty!!!!
    
  • Jon
    Jon over 12 years
    Will that allow for classes that don't implement interfaces and those that do? I'm working with legacy code so old stuff wont have interfaces but new stuff will
  • Wojteq
    Wojteq over 12 years
    It should work with Where(t => t.IsAssignableFrom(typeof(PluginBase)). If not, I'll try to help you.
  • Wojteq
    Wojteq over 12 years
    Of course remove .AsImplementedInterfaces(). I didn't notice this line.
  • Jon
    Jon over 12 years
    That doesn't work either. PluginBase is abstract if that helps
  • Jon
    Jon over 12 years
    If I put my original code back and just take out the where clause it works
  • Jon
    Jon over 12 years
    That works! Could I add the AsImplementedInterfaces for newer classes that do implement interfaces?
  • Wojteq
    Wojteq over 12 years
    Are the classes that extends PluginBase in your current AppDomain?
  • Jehof
    Jehof over 12 years
    I think these two calls should work together. Then the type gets registered with by its base type and all interfaces it implements.
  • Jon
    Jon over 12 years
    Oops, just re-read what I wrote and doesn't make sense. If I have a class that inherits from PluginBase and has a constructor argument of an interface this won't work even with AsImplementedInterfaces. Do I do a new builder registration or can I amend the current code?
  • Jon
    Jon over 12 years
    Yes they are. Jehof's seems to be getting somewhere but I still stuck
  • Jon
    Jon over 12 years
    I just got it working by calling RegisterAssemblyTypes again. Thanks for your help.
  • Nicholas Blumhardt
    Nicholas Blumhardt over 12 years
    Just a note, you don't need the Where call if you use As.
  • Omer Faruk Zorlu
    Omer Faruk Zorlu over 5 years
    That does not works when assembly are not loaded. AppDomain.CurrentDomain.GetAssemblies is only returns loaded assemblies.