.NET Core Dependency Injection of static instance into generic concrete class to satisfy a generic class dependency

Viewed 45

Consider the following AnimalContext<TAnimalType> generic class that requires a factory of IConfigurationFactory<TAnimalType> in its constructor:

public class AnimalContext<TAnimalType> : IAnimalContext<TAnimalType> 
        where TAnimalType : AnimalDefinition
{
    private IConfigurationFactory<TAnimalType> factory;

    public AnimalType AnimalType { get; protected set; }

    public AnimalContext(IConfigurationFactory<TAnimalType> factory)
    {
        this.factory = factory;

        AnimalType = GetAnimalType();
    }
}

To build the dependency we have another class ConfigurationFactory<TConfigurationType> and this class in turn depends on an instance of IFactory:

public class ConfigurationFactory<TConfigurationType> : IConfigurationFactory<TConfigurationType> 
        where TConfigurationType : class
{
    private IFactory factory;

    public ConfigurationFactory(IFactory factory)
    {
        this.factory = factory;
    }
}

IFactory however does not have concrete implementations but rather an abstract class that inherits from IFactory, namely BaseFactory.

public abstract class BaseFactory : IFactory
{
    protected BaseFactory()
    {
    }

    private Type animalType;

    protected Type AnimalType
    {
        get { return this.animalType; }
        set { this.animalType = value; }
    }
}

Finally, we have a cat factory that is a sealed class with a static member CatFactory. As you can imagine we can create a DogFactory, BearFactory etc.

public sealed class CatFactory : BaseFactory
{
    private static CatFactory instance = new CatFactory();

    private CatFactory()
    {
        this.AnimalType = typeof(Cat);
    }

    public static CatFactory Instance
    {
        get { return CatFactory.instance; }
    }
}

The question here is how one registers IConfigurationFactory<TAnimalType> in the startup class so that the right factory gets created using dependency injection. This is some old code I'm porting to .NET Core 5.0 and it uses AutoFAC DI. I would like to use .NET Core's own DI.

Clearly the issue is we somehow have to create a very specific factory dependent on the type but this class is an instance. Only one exists. How do we do this? AutoFAC seemed to be able to handle it with something like the snippet below.

private static void SetupPageContextAndFactory<TAnimalType, TConfigurationFactory, TAnimalContext>( ContainerBuilder builder, AnimalType animalType, IFactory factory )
{
     app.RegisterType<TConfigurationFactory>()
    .WithParameter(
        (p, c) => p.ParameterType == typeof(IFactory),
        (p, c) => factory
        )
        .WithParameter(
        (p, c) => p.ParameterType == typeof(AnimalType),
        (p, c) => animalType
        )
    .As<IConfigurationFactory<TAnimalType>>()
    .Keyed<IAnimalFactory>(animalType)
    .InstancePerRequest();
}
0 Answers
Related