策略模式和两个存储库

时间:2018-07-17 09:13:17

标签: c# dependency-injection repository factory-pattern strategy-pattern

我的业务逻辑中有一个策略模式,该模式引用了两个应用程序。一个是Web MVC应用程序,另一个是Xamarin应用程序。

现在,我想以这种策略模式从数据库中写入/读取数据,但是我有两个不同的存储库。我如何才能将正确的策略注入这种策略模式。

enter image description here

public class LearnStrategy
{
    private ILearnStrategy _learnStrategy = new SimpleLearnStrategy();

    public Guid CardSetId { get; set; }
    public string CardSetName { get; set; }

    public bool Shuffle { get; set; }
    public bool WriteMode { get; set; }

    public bool ReverseMode { get; set; }
    public int SelectedLearnLevel { get; set; }


    public void Execute()
    {
        _learnStrategy.StartLearn();
    }

    public void SetLearnStrategy(ILearnStrategy learningStrategy)
    {
        _learnStrategy = learningStrategy;
    }

    public ILearnStrategy GetStrategy()
    {
        return _learnStrategy;
    }

    public ILearnStrategy ResolveLearnStrategy(LearnModus learnModus)
    {
        switch (learnModus)
        {
            case LearnModus.Exam:
                return new ExamLearnStrategy();
            case LearnModus.Level:
                return new LevelLearnStrategy();
            case LearnModus.Simple:
                return new SimpleLearnStrategy();
            case LearnModus.System:
                return new SystemLearnStrategy();
            default:
                return new SimpleLearnStrategy();
        }
    }
}

其中一项策略

public class SimpleLearnStrategy : ILearnStrategy
{
    public void Dispose()
    {
        throw new NotImplementedException();
    }

    public void StartLearn()
    {
        throw new NotImplementedException();
    }
}

更新


存储库A

public interface IRepositoryA<TEntityType> : IDisposable where
    TEntityType : class
{
    TEntityType Add(TEntityType entity);
    Task<TEntityType> AddAsync(TEntityType entity);
    void Update(TEntityType entity);
    Task UpdateAsync(TEntityType entity);
    void Delete(TEntityType entity);
    void Delete(Expression<Func<TEntityType, bool>> where);
    TEntityType GetById(Guid id);
    Task<TEntityType> GetByIdAsync(Guid id);
    TEntityType Get(Expression<Func<TEntityType, bool>> where);
    Task<TEntityType> GetAsync(Expression<Func<TEntityType, bool>> where, params Expression<Func<TEntityType, object>>[] includeProperties);
    IEnumerable<TEntityType> GetAll();
   // IEnumerable<TEntityType> GetMany(Expression<Func<TEntityType, bool>> where);
    //Task<IEnumerable<TEntityType>> GetManyAsync(Expression<Func<TEntityType, bool>> where,
    //    params Expression<Func<TEntityType, object>>[] includeProperties);
    int Count(Expression<Func<TEntityType, bool>> where);

    IEnumerable<TEntityType> GetMany(Func<IQueryable<TEntityType>, IQueryable<TEntityType>> includeMembers,Expression<Func<TEntityType, bool>> where);
    Task<IEnumerable<TEntityType>> GetManyAsync(Expression<Func<TEntityType, bool>> where);
}

public class RepositoryA<TEntityType> : IRepositoryA<TEntityType>
    where TEntityType : class
{
    readonly admin_MCCardContext _dbContext;
    private readonly DbSet<TEntityType> _dbSet;

    public Repository(admin_MCCardContext dbContext)
    {
        _dbContext = dbContext;
        _dbSet = dbContext.Set<TEntityType>();
    }

    public TEntityType Add(TEntityType entity)
    {
    }

    public async Task<TEntityType> AddAsync(TEntityType entity)
    {
    }

    public void Update(TEntityType entity)
    {
    }

    public async Task UpdateAsync(TEntityType entity)
    {
    }

    public int Count(Expression<Func<TEntityType, bool>> where)
    {
    }

    public void Delete(TEntityType entity)
    {
    }

    public void Delete(Expression<Func<TEntityType, bool>> where)
    {
    }

    public TEntityType Get(Expression<Func<TEntityType, bool>> where)
    {
    }

    public async Task<TEntityType> GetAsync(Expression<Func<TEntityType, bool>> where,
        params Expression<Func<TEntityType, object>>[] includeProperties)
    {
    }

    public IEnumerable<TEntityType> GetAll()
    {
    }

    public TEntityType GetById(Guid id)
    {
    }

    public async Task<TEntityType> GetByIdAsync(Guid id)
    {
    }

    public IEnumerable<TEntityType> GetMany(Expression<Func<TEntityType, bool>> where)
    {
    }

    public async Task<IEnumerable<TEntityType>> GetManyAsync(Expression<Func<TEntityType, bool>> where)
    {
    }

    public IEnumerable<TEntityType> GetMany(Func<IQueryable<TEntityType>,IQueryable<TEntityType>> includeMembers,
        Expression<Func<TEntityType, bool>> where)
    {
    }

    private bool _disposed = false;

    protected virtual void Dispose(bool disposing)
    {
        if (!this._disposed)
        {
            if (disposing)
            {
                _dbContext.Dispose();
            }
        }
        this._disposed = true;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}

储存库B

public interface IRepositoryB<T> : IDisposable where T : class, new()
{
    Task<T> GetAsync(Expression<Func<T, bool>> where);
    Task<List<T>> GetAsync();
    Task<T> GetAsync(Guid id);
    Task<IEnumerable<T>> GetListAsync<TValue>(Expression<Func<T, bool>> where = null, Expression<Func<T, TValue>> orderBy = null);
    AsyncTableQuery<T> AsQueryable();
    Task<int> InsertAsync(T entity);
    Task<int> BulkSyncInsertAsync(IList<T> itemList);
    Task<int> UpdateAsync(T entity);
    Task<int> DeleteAsync(T entity);
    Task<int> CountAsync(Expression<Func<T, bool>> where);

    Task<bool> DeleteAllIdsAsync(string sqlQuery);
}

public class RepositoryB<TEntityType> : IRepositoryB<TEntityType> where TEntityType : class, new()
{
    private static readonly AsyncLock Locker = new AsyncLock();

    private SQLiteAsyncConnection DbContext { get; } = DependencyService.Get<ISQLite>().GetAsyncConnection();

    public Repository()
    {
    }

    public AsyncTableQuery<TEntityType> AsQueryable() => DbContext.Table<TEntityType>();

    public async Task<List<TEntityType>> GetAsync() => await DbContext.Table<TEntityType>().ToListAsync();

    public async Task<TEntityType> GetAsync(Expression<Func<TEntityType, bool>> where) => await DbContext.FindAsync<TEntityType>(where);

    public async Task<TEntityType> GetAsync(Guid id) => await DbContext.FindAsync<TEntityType>(id);

    public async Task<IEnumerable<TEntityType>> GetListAsync<TValue>(Expression<Func<TEntityType, bool>> where = null, Expression<Func<TEntityType, TValue>> orderBy = null)
    {
    }

    public async Task<int> InsertAsync(TEntityType entity) => await DbContext.InsertAsync(entity);

    public async Task<int> BulkSyncInsertAsync(IList<TEntityType> itemList)
    {
    }

    public async Task<int> CountAsync(Expression<Func<TEntityType, bool>> where)
    {
    }

    public async Task<int> UpdateAsync(TEntityType entity) => await DbContext.UpdateAsync(entity);

    public async Task<int> DeleteAsync(TEntityType entity) => await DbContext.DeleteAsync(entity);

    public async Task<bool> DeleteAllIdsAsync(string sqlQuery)
    {
    }

    private bool _disposed = false;

    protected virtual void Dispose(bool disposing)
    {
        if (!this._disposed)
        {
            if (disposing)
            {
                DependencyService.Get<ISQLite>().CloseConnection();
            }
        }
        this._disposed = true;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    } 
}

1 个答案:

答案 0 :(得分:1)

基于注释,当从网络或应用程序中使用该策略时,看起来必须使用给定的存储库。

此处的关键是避免尝试猜测哪个应用程序,而是进一步委派此责任。这就是依赖关系注入的亮点:让调用者为您提供正确的存储库!

首先,必须将这两个存储库归为同一类:

public interface IRepository<T> : IDisposable where T : class
{
    Task UpdateAsync(T entity);
    Task<int> CountAsync(Expression<Func<T, bool>> where);
}
public sealed class RepositoryA<T> : IRepository<T> where T : class
{
    public async Task<int> CountAsync(Expression<Func<T, bool>> where) => throw new NotImplementedException();
    public void Dispose() => throw new NotImplementedException();
    public async Task UpdateAsync(T entity) => throw new NotImplementedException();
    //other methods not common to both repositories
}
public sealed class RepositoryB<T> : IRepository<T> where T : class, new()
{
    public async Task<int> CountAsync(Expression<Func<T, bool>> where) => throw new NotImplementedException();
    public void Dispose() => throw new NotImplementedException();
    public async Task UpdateAsync(T entity) => throw new NotImplementedException();
    //other methods not common to both repositories
}

然后在构造策略时必须提供此抽象:

public ILearnStrategy ResolveLearnStrategy(LearnModus learnModus, IRepository repository)
{
    switch (learnModus)
    {
        case LearnModus.Exam:
            return new ExamLearnStrategy(repository);
        case LearnModus.Level:
            return new LevelLearnStrategy(repository);
        case LearnModus.Simple:
            return new SimpleLearnStrategy(repository);
        case LearnModus.System:
            return new SystemLearnStrategy(repository);
        default:
            return new SimpleLearnStrategy(repository);
    }
}

每个策略都必须接受该存储库并在需要时使用它(为简洁起见,仅示例了1个抽象):

public class SimpleLearnStrategy : ILearnStrategy
{
    private readonly IRepository _repository;
    public SimpleLearnStrategy(IRepository repository) => _repository = repository;
    public void Dispose()
    {
        throw new NotImplementedException();
    }

    public void StartLearn()
    {
        //use _repository for your needs
        throw new NotImplementedException();
    }
}