使用Simple Injector注册通用类型的实例创建者

Tom*_*rek 4 .net c# asp.net-mvc dependency-injection simple-injector

我在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>());
...
Run Code Online (Sandbox Code Playgroud)

IDomainQueryFactory工厂负责创建的实例IQueryable<TEntity>。然后,某些类(例如MVC控制器)仅声明对的依赖IQueryable<Entity1>

我想知道是否有某种方法可以通过单个命令编写这些注册。

Ste*_*ven 5

无法执行此操作,因为与功能合成相比,简单喷射器更喜欢使用类型的合成。这意味着Simple Injector不会轻易允许您注册要在注册过程中使用的通用方法,就像您可以使用通用类型一样。

因此,为了减少样板代码的数量并避免必须更新每个新实体上的配置,您将必须创建一个通用IQueryable<T>实现并将其注册。这是这种实现的样子:

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>();
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以如下注册:

container.RegisterOpenGeneric(typeof(IQueryable<>), typeof(DomainQueryFactoryQueryable<>));
Run Code Online (Sandbox Code Playgroud)

  • 该解决方案完美地工作。我将尝试更多地从功能组成思想入手,对类型组成进行思考。 (2认同)