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.
source to share
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<>));
source to share