如果我有Service类和IRepository,是否需要Repository类?

时间:2012-05-14 17:43:40

标签: asp.net-mvc-3 model-view-controller repository-pattern

阅读后,this question。我想我需要查看我的结构以避免冗余代码。

我目前的结构是控制器 - >存储库 - > IRepository。

存储库看起来像这样:

public class UserRepository : IUserRepository, IDisposable
{
    private StudentSchedulingEntities _context;

    public UserRepository(StudentSchedulingEntities context)
    {
        if (context == null)
            throw new ArgumentNullException("context");

        _context = context;
    }
    public IEnumerable<User> GetUsers()
    {
        return _context.Users.ToList();
    }
    public User GetUserByID(int id)
    {
        return _context.Users.Find(id);

    }
    public void InsertStudent(User user)
    {
        _context.Users.Add(user);
    }
    public void DeleteStudent(int userID)
    {
        User usr = _context.Users.Find(userID);
        _context.Users.Remove(usr);
    }
    public void UpdateStudent(User user)
    {
        _context.Entry(user).State = EntityState.Modified;
    }
    public void Save() {
        _context.SaveChanges();
    }
    public void Dispose()
    {
        Dispose(true); 
        GC.SuppressFinalize(this); 
    }
    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            if (_context != null)
            {
                _context.Dispose();
                _context = null;
            }
        }
    }
}

我的IRepository看起来像这样:

public interface IUserRepository : IDisposable
{
    IEnumerable<User> GetUsers();
    User GetUserByID(int userID);
    void InsertStudent(User user);
    void DeleteStudent(int userID);
    void UpdateStudent(User user);
    void Save();
}

我想避免在服务层再次这样做。我是否需要存储库类,还是应该实现服务层来代替存储库?

2 个答案:

答案 0 :(得分:2)

您的服务层不需要任何存储库实现,它只需使用存储库来查找用户,添加/编辑/删除用户等等。

现在,如果我可以提供一些意见,我建议使用通用存储库。这样,如果你需要创建新的存储库,那就非常简单了。我们使用nopCommerce,他们使用以下代码:

public partial interface IRepository<T> where T : BaseEntity
{
    T GetById(object id);
    void Insert(T entity);
    void Update(T entity);
    void Delete(T entity);
    IQueryable<T> Table { get; }
}

由于它使用Entity Framework,因此这是实现:

/// <summary>
/// Entity Framework repository
/// </summary>
public partial class EfRepository<T> : IRepository<T> where T : BaseEntity
{
    private readonly IDbContext _context;
    private IDbSet<T> _entities;

    /// <summary>
    /// Ctor
    /// </summary>
    /// <param name="context">Object context</param>
    public EfRepository(IDbContext context)
    {
        this._context = context;
    }

    public T GetById(object id)
    {
        return this.Entities.Find(id);
    }

    public void Insert(T entity)
    {
        try
        {
            if (entity == null)
                throw new ArgumentNullException("entity");

            this.Entities.Add(entity);

            this._context.SaveChanges();
        }
        catch (DbEntityValidationException dbEx)
        {
            var msg = string.Empty;

            foreach (var validationErrors in dbEx.EntityValidationErrors)
                foreach (var validationError in validationErrors.ValidationErrors)
                    msg += string.Format("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage) + Environment.NewLine;

            var fail = new Exception(msg, dbEx);
            //Debug.WriteLine(fail.Message, fail);
            throw fail;
        }
    }

    public void Update(T entity)
    {
        try
        {
            if (entity == null)
                throw new ArgumentNullException("entity");

            this._context.SaveChanges();
        }
        catch (DbEntityValidationException dbEx)
        {
            var msg = string.Empty;

            foreach (var validationErrors in dbEx.EntityValidationErrors)
                foreach (var validationError in validationErrors.ValidationErrors)
                    msg += Environment.NewLine + string.Format("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage);

            var fail = new Exception(msg, dbEx);
            //Debug.WriteLine(fail.Message, fail);
            throw fail;
        }
    }

    public void Delete(T entity)
    {
        try
        {
            if (entity == null)
                throw new ArgumentNullException("entity");

            this.Entities.Remove(entity);

            this._context.SaveChanges();
        }
        catch (DbEntityValidationException dbEx)
        {
            var msg = string.Empty;

            foreach (var validationErrors in dbEx.EntityValidationErrors)
                foreach (var validationError in validationErrors.ValidationErrors)
                    msg += Environment.NewLine + string.Format("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage);

            var fail = new Exception(msg, dbEx);
            //Debug.WriteLine(fail.Message, fail);
            throw fail;
        }
    }

    public virtual IQueryable<T> Table
    {
        get
        {
            return this.Entities;
        }
    }

    private IDbSet<T> Entities
    {
        get
        {
            if (_entities == null)
                _entities = _context.Set<T>();
            return _entities;
        }
    }
        //TODO implement IDisposable interface
}

现在它就像IRepository<User>IRepository<Whatever>一样简单。

答案 1 :(得分:0)

绝对没有冗余代码:-)当你说:

我目前的结构是控制器 - &gt;存储库 - &gt;

Controller是否继承自Repository?你也不想要那个。存储库层通常与存储(XML,数据库,文件系统等)接口,并映射到存储库友好类。另一层管理存储库层到本机业务/服务类的映射。