具有服务层,业务层和实体框架的N层体系结构

时间:2012-08-22 19:46:06

标签: c# asp.net-mvc asp.net-mvc-3 entity-framework asp.net-mvc-2

只是希望得到一些反馈/帮助我正在构建我的应用程序。我目前的解决方案结构如下所示:

  • UI(实际MVC应用程序)
  • Core(仅限Controllers& ViewModels)
  • 服务
  • BLL
  • 数据(实体框架DbContext,映射到域对象)
  • 域(简单POCO对象)
  • 接口

其他东西

  • Ninject将DbContext注入Controller(按请求)
  • AutoMapper将域对象映射到ViewModel

所有程序集都引用了Interfaces项目,顾名思义,它只不过是简单的接口(即IDbContext,IRepository等)。

服务项目将所有其他事物“联系在一起”。它是唯一一个直接引用数据访问层(实体框架)的程序集。

我在下面提供了一些代码:

Controller的示例如下所示:

namespace Core.Controllers
{
    public class HomeController : Controller
    {
        private IDbContext dbContext;

        public HomeController(IDbContext dbContext)
        {
            this.dbContext = dbContext;
        }

        public ActionResult Users()
        {
            UserService userService = new UserService(dbContext);
            var users = userService.GetAllUsers();
            return View(Mapper.Map<IEnumerable<UserListViewModel>>(users));
        }
        ...

UserService类:

namespace Services
{
    public class UserService
    {
        private readonly IDbContext dbContext;

        public UserService(IDbContext dbContext)
        {
            this.dbContext = dbContext;
        }

        public IEnumerable<User> GetAllUsers()
        {
            IRepository<User> userRepository = new Repository<User>(dbContext);
            UserBLL userBLL = new UserBLL(userRepository);
            return userBLL.GetAllUsers();
        }
        ...

最后,业务层类:

namespace BLL
{
    public class UserBLL
    {
        private readonly IRepository<User> userRepository;

        public UserBLL(IRepository<User> userRepository)
        {
            this.userRepository = userRepository;
        }

        public IEnumerable<User> GetAllUsers()
        {
            return userRepository.Get();
        }
        ...

我正在寻找一些反馈/改进方法。我注意到,对于基本任务,我的服务层方法将与业务层方法完全相同(即“传递”功能)。我希望这个抽象将有助于更复杂的任务,这些任务可能需要调用多个业务层方法。将业务逻辑包含在服务层中会更好吗?

4 个答案:

答案 0 :(得分:9)

从快速浏览一下,我不认为您的服务和控制器/核心层应该以这种方式将db上下文注入其中。它们实际上并不直接依赖它,并且以这种方式进行它会导致一些不理想的耦合。核心层应该注入用户服务,用户服务和BLL应该注入存储库。存储库应该具有由DI框架注入的dbcontext,而不是作为依赖项传递。

答案 1 :(得分:4)

为什么在直接在服务中创建依赖项时使用依赖项注入?

public IEnumerable<User> GetAllUsers()
{
    IRepository<User> userRepository = new Repository<User>(dbContext);
    UserBLL userBLL = new UserBLL(userRepository);
    return userBLL.GetAllUsers();
}

顺便说一下。为什么你在实际上什么都不做的时候会使用这么多层?您的示例代码只显示直接在控制器中使用上下文将产生相同的结果,而没有三个包装器无用的层。这可能只是你的例子的问题,但每一层都应该带来一些额外的逻辑。如果您只是用它来调用较低层的内容,那么您很可能会对代码进行过多的构建。这被称为洋葱建筑。这也是为什么在需要时添加图层并不是一个不好的做法 - 而不是在前面。

答案 2 :(得分:1)

请检查一下:http://www.primaryobjects.com/CMS/Article122.aspx EF存储库模式+工作单元模式。至于你的其他层,它实际上取决于应用程序以及它需要完成的任务。请提供您正在尝试做的更多详细信息。

答案 3 :(得分:0)

组织项目和层设计的一些改进可以通过专注于使Domain对象正确来完成。

你说你有简单的POCO对象作为域,但域对象应该是具有业务的所有&#34;状态和行为&#34; 的对象。这意味着您不需要将BLL和域程序集分开。 一旦定义了Domain对象,就可以使用EF来创建上下文和实体类(除非与域对象相比没有其他行为,但它们不是Domain类,但仍然使它们不同可能对将来的要求有利)。

另一个小问题是,我认为在域和服务层中分布的接口在任何人理解每个层时都是更好的。