Autofac registering all subtypes keyed according to a property

465 views Asked by At

The following scenario:

public enum ChildType
{
    Type1,
    Type2,
    Type3
}

public abstract class MyParentClass
{
    public abstract ChildType Id { get; }
}

public class Child1 : MyParentClass
{
    public override ChildType Id { get { return ChildType.Type1; } }
} 

public class Child2 : MyParentClass
{
    public override ChildType Id { get { return ChildType.Type2; } }
} 

public class Child3 : MyParentClass
{
    public override ChildType Id { get { return ChildType.Type3; } }
} 

and i would like to use autofac to register all the subtypes using their id as a key, so something like:

builder.RegisterAssemblyTypes(ThisAssembly)
            .Where(type => type.IsSubclassOf(typeof(MyParentClass)))
            .Keyed<MyParentClass>(c => c.Id)
            .SingleInstance();

now obviously the above doesn't work, but is there some way to achieve that without registering each subclass separately? I want to then be able to access them by the enum, i.e. at runtime when i don't know what the value of the enum will be:

public static MyParentClass GetSubClassByEnum(ChildType id)
{
    AutofacHostFactory.Container.ResolveKeyed<MyParentClass>(id);
}
1

There are 1 answers

1
Travis Illig On BEST ANSWER

Unfortunately you probably won't be able to get exactly this setup working because it's sort of a chicken/egg problem - you want to resolve an object based on information that won't be available... unless you resolve the object.

One way to get this working is to use attributes rather than properties. Attributes are available before the type is instantiated so you could store the info there and achieve the desired result.

Autofac has attribute metadata support that allows you to create custom attributes to provide this sort of information. You could create an attribute that gets inherited and only allows one instance per class. Apply it with the default value to your base class, then when you need to override apply a new attribute on the derived class.

There is plenty of documentation with examples on the Autofac doc site showing how to work with this.