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>());
...
The IDomainQueryFactory
factory is responsible for creating the instances of IQueryable<TEntity>
. Some class (like MVC controller) then declares dependency only on IQueryable<Entity1>
.
I am wondering if there is some way of writing these registrations with a single command.
There is no way to do this, because Simple Injector favors composition using types over functional composition. This means that Simple Injector does not easily allow you to register a generic method to be used in the registration process, just as you would be able to use a generic type.
So to reduce the amount of boilerplate code and prevent having to update the configuration on each new entity, you will have to create a generic IQueryable<T>
implementation and register that. This is how this implementation would look 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 this as follows:
container.RegisterOpenGeneric(typeof(IQueryable<>), typeof(DomainQueryFactoryQueryable<>));