将派生的存储库注册为立即实现的接口

时间:2013-03-31 04:33:22

标签: autofac

我有使用Repository Pattern的情况,我希望有一些额外的存储库与任何实体都不对应。

例如,这里有一个:

 public class TargetRepository : RepositoryBase<Target>, ITargetRepository
{
    public TargetRepository(IDatabaseFactory databaseFactory)
        :base(databaseFactory)
    {
    }

            public IEnumerable<Target>  GetValidTargets(){ ... }
}
public interface ITargetRepository : IRepository<Target>
{
            IEnumerable<Target>  GetValidTargets();
}

Target是一个实体。

然后我想要一些像这样的其他存储库:

  public class ScatterPlotRepositoryProxy : TargetRepository, IScatterPlotRepositoryProxy
{
    public ScatterPlotRepositoryProxy(IDatabaseFactory databaseFactory)
        :base(databaseFactory)
    { }

            public IEnumerable<ScatterPlotModel> GetSavedScatterPlots() {
                   this.GetValidTargets().Select(t => new ScatterPlotModel{ ... });
            }
}

public interface IScatterPlotRepositoryProxy
{
         IEnumerable<ScatterPlotModel> GetSavedScatterPlots()
}

请注意这一点是如何从TargetRepository而不是RepositoryBase<Entity>继承的。这是因为ScatterPlotModel不是一个实体,甚至没有持久化。但是,我想要另一层分离,这样我的TargetRespository就不会混淆所有不同图表类型的方法。

我还没有实际实现过,所以还没有错误。但我预见到我的Autofac DI电话会在以后引起问题所以我提前要求。

如何使用Autofac正确注册这些“存储库代理”?目前我有这个:

builder.RegisterAssemblyTypes(typeof(TargetRepository ).Assembly).Where(t => t.Name.EndsWith("Repository")).AsImplementedInterfaces().InstancePerApiRequest();

添加这个似乎会发生冲突:

 builder.RegisterAssemblyTypes(typeof(TargetRepository ).Assembly).Where(t => t.Name.EndsWith("RepositoryProxy")).AsImplementedInterfaces().InstancePerHttpRequest();

我是否会得到我期望的行为(IScatterPlotRepositoryProxy将解析为ScatterPlotRepositoryProxyITargetRepository应继续解析为TargetRepository,尽管ScatterPlotRepositoryProxy也会从{{1}}实施基础库)?

尝试从程序集中一次性完成所有操作,以避免为每个存储库添加行。

1 个答案:

答案 0 :(得分:3)

你错过了系统中的抽象概念。这会给你带来各种各样的麻烦和你已经目睹的痛苦。

您需要的是对系统中查询的常见抽象。这消除了使用自定义存储库接口的需要。诸如ITargetRepository之类的自定义存储库接口违反了五个SOLID原则中的三个,这毫无疑问会导致各种可维护性问题。

我过去曾写过一篇关于这个主题的文章,所以我不会在这里重复一遍(让我们保留DRY),但你一定要读这篇文章:Meanwhile... on the query side of my architecture。< / p>

在应用该文章中给出的体系结构指南时,使用Autofac注册存储库和查询都没有问题。这只是一个问题:

builder.RegisterAssemblyTypes(typeof(IRepository<>).Assembly)
    .AsClosedTypesOf(typeof(IRepository<>));

builder.RegisterAssemblyTypes(typeof(IQueryHandler<,>).Assembly)
    .AsClosedTypesOf(typeof(IQueryHandler<,>));