1

我有一种使用存储库模式的情况,我希望有一些不对应于任何实体的额外存储库。

例如,这是一个:

 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()
}

注意这个是如何从TargetRepositorynot继承的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将解决ScatterPlotRepositoryProxy并且ITargetRepository应该继续解决,TargetRepository尽管ScatterPlotRepositoryProxy也从基本存储库实现它)?

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

4

1 回答 1

3

您的系统中缺少抽象。这给你带来了各种各样的麻烦和你已经目睹的痛苦。

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

我过去写过一篇关于这个主题的文章,所以我不会在这里重复自己(让我们保持干燥),但你绝对应该阅读这篇文章:同时......在我的架构的查询方面

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

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

builder.RegisterAssemblyTypes(typeof(IQueryHandler<,>).Assembly)
    .AsClosedTypesOf(typeof(IQueryHandler<,>));
于 2013-03-31T11:05:33.927 回答