加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-mvc-4 – 工作单元和通用存储库与实体框架5

发布时间:2020-12-15 19:06:46 所属栏目:asp.Net 来源:网络整理
导读:我使用ASP.NET MVC 4与Entity Framework 5.我有模型类和实体映射,以将现有表映射到这些模型类。所有这一切都很好,工作伟大。 现在我想嘲笑这个。我创建了工作单元,它接受DataContext并使用通用存储库。在那之后,我构建服务,以便能够从多个存储库中获取
我使用ASP.NET MVC 4与Entity Framework 5.我有模型类和实体映射,以将现有表映射到这些模型类。所有这一切都很好,工作伟大。

现在我想嘲笑这个。我创建了工作单元,它接受DataContext并使用通用存储库。在那之后,我构建服务,以便能够从多个存储库中获取数据,而只需要有一个DataContext的实例。这也工作伟大。

现在到问题:我想测试的服务,用模拟数据。当我创建Unit Of Work实例时,我想要能够插入一个被嘲笑的DataContext,而不是真正的DataContext。

我试图创建一个IContext接口,让真正的嘲笑DataContext实现,但遇到了DbSet的问题。我试图使用IDbSet和创建一个FakeDbSet,但没有成功。我也读在互联网上嘲笑上下文与IDbSet和使用FakeDbSet是一个坏的方法。

你有什么想法将是实现这一最好的方法吗?我现在是我想保留的行为,但真的想能够从DataContext中的Model类中模拟数据。

我知道实体框架已经附带了工作单位的行为,你不需要添加额外的行为。但我想包装在另一个类,跟踪所有的库(称为UnitOfWork类)。

编辑:我写了两篇文章解释我的解决方案与LINQ和实体框架。

http://gaui.is/how-to-mock-the-datacontext-linq/

http://gaui.is/how-to-mock-the-datacontext-entity-framework/

这里是我的代码:

IRepository.cs

public interface IRepository<T> where T : class
{
    void Add(T entity);
    void Delete(T entity);
    void Update(T entity);
    T GetById(long Id);
    IEnumerable<T> All();
    IEnumerable<T> Find(Expression<Func<T,bool>> predicate);
}

IUnitOfWork.cs

public interface IUnitOfWork : IDisposable
{
    IRepository<TEntity> GetRepository<TEntity>() where TEntity : class;
    void Save();
}

Repository.cs

public class Repository<T> : IRepository<T> where T : class
{
    private readonly IDbContext _context;
    private readonly IDbSet<T> _dbset;

    public Repository(IDbContext context)
    {
        _context = context;
        _dbset = context.Set<T>();
    }

    public virtual void Add(T entity)
    {
        _dbset.Add(entity);
    }

    public virtual void Delete(T entity)
    {
        var entry = _context.Entry(entity);
        entry.State = System.Data.EntityState.Deleted;
    }

    public virtual void Update(T entity)
    {
        var entry = _context.Entry(entity);
        _dbset.Attach(entity);
        entry.State = System.Data.EntityState.Modified;
    }

    public virtual T GetById(long id)
    {
        return _dbset.Find(id);
    }

    public virtual IEnumerable<T> All()
    {
        return _dbset;
    }

    public IEnumerable<T> Find(Expression<Func<T,bool>> predicate)
    {
        return _dbset.Where(predicate);
    }
}

UnitOfWork.cs

public class UnitOfWork<TContext> : IUnitOfWork where TContext : IDbContext,new()
{
    private readonly IDbContext _ctx;
    private Dictionary<Type,object> _repositories;
    private bool _disposed;

    public UnitOfWork()
    {
        _ctx = new TContext();
        _repositories = new Dictionary<Type,object>();
        _disposed = false;
    }

    public IRepository<TEntity> GetRepository<TEntity>() where TEntity : class
    {
        if (_repositories.Keys.Contains(typeof(TEntity)))
            return _repositories[typeof(TEntity)] as IRepository<TEntity>;

        var repository = new Repository<TEntity>(_ctx);
        _repositories.Add(typeof(TEntity),repository);
        return repository;
    }

    public void Save()
    {
        _ctx.SaveChanges();
    }

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

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

            this._disposed = true;
        }
    }
}

ExampleService.cs

public class ExampleService
{
    private IRepository<Example> m_repo;

    public ExampleService(IUnitOfWork uow)
    {
        m_repo = uow.GetRepository<Example>();
    }

    public void Add(Example Example)
    {
        m_repo.Add(Example);
    }

    public IEnumerable<Example> getAll()
    {
        return m_repo.All();
    }
}

ExampleController.cs

public IEnumerable<Example> GetAll()
{
    // Create Unit Of Work object
    IUnitOfWork uow = new UnitOfWork<AppDataContext>();

    // Create Service with Unit Of Work attached to the DataContext
    ExampleService service = new ExampleService(uow);

    return service.getAll();
}

解决方法

你的ExampleService类期待IUnitOfWork,这意味着你只需要另一个IUnitOfWork是一个Mock,它的GetRepository()方法将返回一个IRepository Mock。

例如(不是真的一个Mock,但内存中的存根):

public InMemoryRepository<T> : IRepository<T> where T : class
  {
        ........
  }

  public InMemoryUnitOfWork : IUnitOfWork
  {
       public IRepository<TEntity> GetRepository<TEntity>() where TEntity : class
       {
            return new InMemoryRepository<TEntity>();
       }
  }

然后:

public IEnumerable<Example> GetAll()
{
    // Create Unit Of Work object
    IUnitOfWork uow = new InMemoryUnitOfWork();

    // Create Service with Unit Of Work
    ExampleService service = new ExampleService(uow);

    return service.getAll();
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读