Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Registering implementations of base class with Autofac to pass in via IEnumerable

I have a base class, and a series of other classes inheriting from this:
(Please excuse the over-used animal analogy)

public abstract class Animal { }

public class Dog : Animal { }

public class Cat : Animal { }

I then have a class that has a dependancy on an IEnumerable<Animal>

public class AnimalFeeder
{
    private readonly IEnumerable<Animal> _animals;

    public AnimalFeeder(IEnumerable<Animal> animals )
    {
        _animals = animals;
    }
}

If I manually do something like this:

var animals =
    typeof(Animal).Assembly.GetTypes()
        .Where(x => x.IsSubclassOf(typeof(Animal)))
        .ToList();

Then I can see that this returns Dog and Cat

However, when I try to wire up my Autofac like this:

builder.RegisterAssemblyTypes(typeof(Animal).Assembly)
    .Where(t => t.IsSubclassOf(typeof(Animal)));

builder.RegisterType<AnimalFeeder>();

When AnimalFeeder is instantiated, there are no Animal passed in to the constructor.

Have I missed something?

like image 973
Alex Avatar asked Dec 04 '13 10:12

Alex


People also ask

How do I register an Autofac service?

Register by Type var builder = new ContainerBuilder(); builder. RegisterType<ConsoleLogger>(); builder. RegisterType(typeof(ConfigReader)); When using reflection-based components, Autofac automatically uses the constructor for your class with the most parameters that are able to be obtained from the container.

How do I register a generic repository in Autofac?

You need to exactly write like this: builder. RegisterGeneric(typeof(RepositoryBase<>)) . As(typeof(IRepository<>)); note the empty <> and it will register your Repository for all of your entites.

How do I get Autofac containers?

From Visual Studio, you can get it via NuGet. The package name is Autofac. Alternatively, the NuGet package can be downloaded from the GitHub repository (https://github.com/autofac/Autofac/releases).


1 Answers

You are missing the As<Animal>() call in your registration.

Without it Autofac will register your types with the default AsSelf() setting so you won't get your classes if you ask for base type with IEnumerable<Animal> only if you use the sub-types like Dog and Cat.

So change your registration to:

builder.RegisterAssemblyTypes(typeof(Animal).Assembly)
     .Where(t => t.IsSubclassOf(typeof(Animal)))
     .As<Animal>();
like image 55
nemesv Avatar answered Nov 15 '22 18:11

nemesv