Asp.net mvc ASP.NETMVC软件设计模式:DI、存储库、服务层

Asp.net mvc ASP.NETMVC软件设计模式:DI、存储库、服务层,asp.net-mvc,Asp.net Mvc,编辑 我是否应该将服务层和存储库层放在一个项目中,以便web项目能够引用DbContext对象?现在我的web(控制器)无法引用dbcontext对象。正确的方法是什么 // service and repository are together (View <- Controller) -> (Service -> Repository -> EF DbContext) -> (DB) // separate service and repository lay

编辑

我是否应该将服务层和存储库层放在一个项目中,以便web项目能够引用DbContext对象?现在我的web(控制器)无法引用dbcontext对象。正确的方法是什么

// service and repository are together
(View <- Controller) -> (Service -> Repository -> EF DbContext) -> (DB) 
// separate service and repository layer
(View <- Controller) -> (Service) -> (Repository -> EF DbContext) -> (DB)

我相信您确实应该在您的
I假定
通用接口中添加一个
TEntity GetById(intid)

为什么??因为如果您不这样做,并且如果您想在业务层上获取单个记录,那么您只有两个选项(在存储库、数据访问层上):

  • 返回一个完整的“不吉利”集合,这意味着您将返回(比如)100000条记录以使用单个记录
  • 返回一个惰性集合,如
    IQueryable
    ,它允许您从数据库中获取一条记录,但可能会导致大量错误
  • 第一种选择显然是错误的。第二个是有争议的,但是(除非你的项目让你作为一个开发人员,并且你真的知道你在做什么),它是潜在的泄漏和不安全的。因此,如果您确实需要一条记录(有时您肯定会这样做),请公开一个方法来实现这一点

    话虽如此,您也应该公开
    IQueryable All{get;}
    ,原因与上述完全相同。改为使用
    IEnumerable All{get;}
    ,并通过调用
    context.Set().ToList()
    使您的具体泛型存储库类返回一个真实的集合

    编辑

    关于IDisposable:

    实现IDisposable接口的原因只有两个(相关的):

  • 处置非托管资源
  • 一种很酷的生活方式

  • 在您的情况下,您可能应该在存储库实现中使用它。请查看以了解更多信息。

    -1,尽管您对GetById有很好的了解,但这并不是OP的任何问题的答案。@Levitikon:他问了关于
    IDisposable
    ,我回答了。这是一个答案(至少我是这样学会数数的,对你不太清楚:P)
    public interface IRepository<TEntity>
    {
        IQueryable<TEntity> All { get; }
        void Create(TEntity item);
        void Update(TEntity item);
        void Delete(TEntity item);
        void SaveChanges();
    }
    
    public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
    {
        STOREEntities context;
        public Repository()
        {
            context = new STOREEntities();
        }
        public IQueryable<TEntity> All
        {
            get
            {
                return context.Set<TEntity>();
            }
        }
        public void Create(TEntity item)
        {
            context.Set<TEntity>().Add(item);
        }
        public void Update(TEntity item)
        {
            context.Entry<TEntity>(item).State = System.Data.EntityState.Modified;
        }
        public void Delete(TEntity item)
        {
            context.Set<TEntity>().Remove(item);
        }
        public void SaveChanges()
        {
            context.SaveChanges();
        }
    }
    
    public interface IProductService
    {
        IEnumerable<Product> Products { get; }
        IEnumerable<Product> Get(Expression<Func<Product, Boolean>> filter);
        Product GetByProductId(int productId);
        void AddProduct(Product product);
        void EditProduct(Product product);
        void RemoveProduct(Product product);
        void SaveChanges();
    }
    
        public class ProductService : IProductService
    {
        IRepository<Product> repository; //Inject
        public ProductService(IRepository<Product> repo)
        {
            repository = repo;
        }
        public IEnumerable<Product> Products
        {
            get { return repository.All; }
        }
        public IEnumerable<Product> Get(Expression<Func<Product, bool>> filter)
        {
            return repository.All.Where(filter);
        }
        public Product GetByProductId(int productId)
        {
            return repository.All.SingleOrDefault(p => p.ProductID == productId);
        }
        public void AddProduct(Product product)
        {
            repository.Create(product);
        }
        public void EditProduct(Product product)
        {
            repository.Update(product);
        }
        public void RemoveProduct(Product product)
        {
            repository.Delete(product);
        }
        public void SaveChanges()
        {
            repository.SaveChanges();
        }
    }
    
    public class ProductController : Controller
    {
        IProductService productService; //inject
        public ProductController(IProductService service)
        {
            productService = service;
        }
        public ActionResult Index()
        {
            var products = productService.Products; //retrieve from service layer
            return View(products);
        }
    }