Instantiate an instance for a generic type using a simple injector

I have the following configuration in Simple Injector:

c.Register<IQueryable<Entity1>>(() => c.GetInstance<IDomainQueryFactory>().Query<Entity1>());
c.Register<IQueryable<Entity2>>(() => c.GetInstance<IDomainQueryFactory>().Query<Entity2>());
c.Register<IQueryable<Entity3>>(() => c.GetInstance<IDomainQueryFactory>().Query<Entity3>());
c.Register<IQueryable<Entity4>>(() => c.GetInstance<IDomainQueryFactory>().Query<Entity4>());
...

      

IDomainQueryFactory

factory is responsible for creating instances IQueryable<TEntity>

. Some classes (for example, MVC controller) declare dependencies only on IQueryable<Entity1>

.

I am wondering if there is a way to write these registrations with a single command.

+3


source to share


1 answer


There is no way to do this because Simple Injector supports type composition over functional composition. This means that Simple Injector does not allow you to register a generic method to be used in the registration process, in the same way that you can use a generic type.

So, in order to reduce the amount of boilerplate code and prevent the configuration from being updated for every new object, you will need to create a generic implementation IQueryable<T>

and register it. This is what this implementation looks like:

public sealed class DomainQueryFactoryQueryable<T> : IQueryable<T>
{
    private readonly IDomainQueryFactory factory;

    public DomainQueryFactoryQueryable(IDomainQueryFactory factory) {
        this.factory = factory;
    }

    public Type ElementType { get { return this.GetQuery().ElementType; } }
    public Expression Expression { get { return this.GetQuery().Expression; } }
    public IQueryProvider Provider { get { return this.GetQuery().Provider; } }

    public IEnumerator<T> GetEnumerator() {
        return this.GetQuery().GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator() {
        return this.GetEnumerator();
    }

    private IQueryable<T> GetQuery() { 
        return this.factory.Query<T>();
    }
}

      



And you can register it like this:

container.RegisterOpenGeneric(typeof(IQueryable<>), typeof(DomainQueryFactoryQueryable<>));

      

+4


source







All Articles