简体   繁体   中英

Repository Pattern: Dealing with Identical Repositories

I have four very similar but hierarchical entities. Each one has a foreign key to the previous and contains collections of the next ones.

Part of entity

Right now, these entities have four identical repositories:

Repository

The implementations of the two methods will differ slightly for each.

Is there a design pattern that will allow me to merge all four into one while at the same time allowing me to extend functionality if needed ?

I tried to do this:

 public class DivisionRepository : IDivisionRepository
{
    private DbContext dbContext;
    private IDbSet<PrimaryDivision> primaryDivisionsEntitySet;
    private IDbSet<SecondaryDivision> secondaryDivisionsEntitySet;
    private IDbSet<TertiaryDivision> tertiaryDivisionsEntitySet;
    private IDbSet<QuaternaryDivision> quaternaryDivisionsEntitySet;

    public DivisionRepository(DbContext dbContext)
    {
        this.dbContext = dbContext;
        this.primaryDivisionsEntitySet = dbContext.Set<PrimaryDivision>();
        this.secondaryDivisionsEntitySet = dbContext.Set<SecondaryDivision>();
        this.tertiaryDivisionsEntitySet = dbContext.Set<TertiaryDivision>();
        this.quaternaryDivisionsEntitySet = dbContext.Set<QuaternaryDivision>();
    }

    public IDivision Find(Type type, object id)
    {
        if (type == typeof(PrimaryDivision))
        {
            return this.primaryDivisionsEntitySet.Find(id);
        } 
        else if (type == typeof(SecondaryDivision))
        {
            return this.secondaryDivisionsEntitySet.Find(id);
        }
        else if (type == typeof(TertiaryDivision))
        {
            return this.tertiaryDivisionsEntitySet.Find(id);
        }
        else if (type == typeof(QuaternaryDivision))
        {
            return this.quaternaryDivisionsEntitySet.Find(id);
        }

        throw new ArgumentException("The type provided was incorrect.");

}

CRUD operations continue in similar fashion.

However, it didn't seem like the most optimal solution, so I reverted back to the hodgepodge of interfaces and classes I have now (two per repository).

Thank you

I would do this using what I call a composable repository .

public static T SpecialFind(this IQueryable<T> entities, int id) where T: IDivision
{
    return entities.FirstOrDefault(x=>x.Id == id);
}

usage:

ctx.TertiaryDivisions.SpecialFind(1);

The benefit of doing this is that it gives really nice reuse patterns, especially with more complex scenarios.

however if you are absolutely set on a repository pattern the same basic principal applies:

public T Find<T>(object id) where T : IDivision
{
    return dbContext.Set<T>().Find(id);
}

Alternately you could put the generic on the whole repository.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM