gpt4 book ai didi

asp.net-mvc - ASP.NET MVC 软件设计模式 : DI, 存储库,服务层

转载 作者:行者123 更新时间:2023-12-04 15:47:07 24 4
gpt4 key购买 nike

编辑

我应该将服务层和存储库层放在一个项目中,以便 Web 项目能够引用 DbContext 对象吗?现在我的网络( Controller )无法引用 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)

以下是原始问题

我知道 SO 是一个很好的社区,可以发布我关于 mvc 设计模式的问题。请给我您的建议,我将感谢您的帮助。谢谢!

我们正在计划一个新项目,我们的首要任务是开发一个可扩展且松耦合的应用程序。

我是软件开发的新手;我在 MVC Music Store Tutorial 上做了一些阅读,然后是一本名为 Pro ASP.NET MVC 3 Framework by Steven Sanderson (Apress) 的书,从书中,我了解了 DDD(域驱动设计)和其他一些概念,如存储库和依赖注入(inject)。跟着本书搭建了SportsStore网站,对DI有了一些基本的了解。但是我个人认为这个例子没有分离业务逻辑层,所以我研究了一下,发现了一个模式叫Service Layer Pattern,据我了解,它分离了业务逻辑层。基于此,我为我的新项目(下面的示例项目)提出了一个结构。

我需要执行 一次性界面?如果是,在哪里以及为什么?
这种结构对于一个相对较大的项目是否可行?

示例数据库设计: Product(one)----(many)ProductCategoryRs(many)----(one)Category

该解决方案包含 3 个项目:存储库、服务、Web

存储库:

定义IRepository接口(interface),基本CRUD操作

这些签名是否足够?我应该添加 TEntity GetById(object id); 吗?
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();
}
}

服务:
定义 IProductService 接口(interface),在这里扩展业务逻辑。

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();
}
}

Web 项目,从服务中检索数据并转换为 View 模型和显示。
产品 Controller 代码

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);
}
}

最佳答案

我相信你真的应该添加 TEntity GetById(int id)给您的IRepository<TEntity>通用接口(interface)。

为什么?因为如果你不这样做,并且如果你想在你的业务层获取一条记录,你只有两个选择(在存储库,数据访问层):

  • 返回一个完整的“unlazy”集合,这意味着您将返回 100,000 条记录以使用单个记录。
  • 返回一个惰性集合,如 IQueryable<TEntity> ,是的,这将允许您从数据库中获取一条记录,但可能会导致大量 nasty side-effects .

  • 第一个选项显然是错误的。第二个是有争议的,但是(除非你的项目有你作为一个开发人员,并且你真的很清楚自己在做什么)它可能会泄漏和不安全。因此,如果您确实需要一条记录(有时您肯定会这样做),请公开一个可以做到这一点的方法。

    话虽如此,你也应该 不是 揭露 IQueryable<TEntity> All { get; } ,原因与上述完全相同。使用 IEnumerable<TEntity> All { get; }而是通过调用 context.Set<TEntity>().ToList() 使您的具体通用存储库类返回一个真实的集合。例如。

    编辑

    关于 IDisposable:

    我能想到的实现 IDisposable 接口(interface)的原因只有两个(相关):
  • 处置非托管资源
  • implementing the RAII pattern 的一个很酷的方式.

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

    关于asp.net-mvc - ASP.NET MVC 软件设计模式 : DI, 存储库,服务层,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9632475/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com