11

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?

Alex
  • 35,969
  • 49
  • 197
  • 322
  • 2
    You are probably missing the `As()` in your registartion: `builder.RegisterAssemblyTypes(typeof(Animal).Assembly) .Where(t => t.IsSubclassOf(typeof(Animal))).As();` – nemesv Dec 04 '13 at 10:38
  • Might want to convert that comment to an answer! ;-) Thanks – Alex Dec 04 '13 at 10:48
  • Looks like I have a drive-by downvoter.... – Alex Dec 04 '13 at 11:07

1 Answers1

23

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>();
nemesv
  • 135,824
  • 16
  • 405
  • 353
  • I know this question is old but what if you want to register a named subclass of the abstract class? – Cizaphil Jun 16 '16 at 05:21
  • 1
    Named registrations can be also resolved with `IEnumarable` when they are registered with the type **and** the name. So `builder.RegisterType().As().Named("Dog"); builder.RegisterType().As().Named("Cat");` in this case `IEnumerable` will return both, but you can also resolve the individual ones with: `container.ResolveNamed("Dog");`. You can even combine it with the assembly scanning: `builder.RegisterAssemblyTypes(...).As();` and then register your named ones additionally: `builder.RegisterType().Named("Dog");` – nemesv Jun 16 '16 at 05:52