简体   繁体   English

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

[英]N-Tier Architecture with Service Layer, Business Layer, and Entity Framework

Just wanted some feedback/help with the way I'm architecturing my application. 只是希望得到一些反馈/帮助,我正在构建我的应用程序。 My current solution structure looks something like this: 我目前的解决方案结构如下所示:

  • UI (Actual MVC application) UI(实际MVC应用程序)
  • Core (only Controllers & ViewModels) 核心(仅限控制器和ViewModels)
  • Services 服务
  • BLL BLL
  • Data (Entity framework DbContext, mapped to Domain objects) 数据(实体框架DbContext,映射到Domain对象)
  • Domain (Simple POCO objects) 域(简单POCO对象)
  • Interfaces 接口

Other stuff 其他的东西

  • Ninject to inject DbContext into Controller (per request) Ninject将DbContext注入Controller(每个请求)
  • AutoMapper to map Domain objects to ViewModel AutoMapper将域对象映射到ViewModel

All assemblies have a reference to the Interfaces project, which, as the name suggests, is nothing more than simple interfaces (ie IDbContext, IRepository, etc). 所有程序集都引用了Interfaces项目,顾名思义,它只不过是简单的接口(即IDbContext,IRepository等)。

The Services project "ties" together everything else. 服务项目将所有其他事物“联系在一起”。 It is the only assembly which has a direct reference to the Data access layer (Entity Framework). 它是唯一一个直接引用数据访问层(实体框架)的程序集。

I've provided some code below: 我在下面提供了一些代码:

An example of a Controller looks like this: 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));
        }
        ...

The UserService class: 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();
        }
        ...

Finally, the business layer class: 最后,业务层类:

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

I'm looking for some feedback/ways to improve. 我正在寻找一些反馈/方法来改进。 I notice that for basic tasks, my service layer methods will be exactly the same as the business layer methods (ie "pass through" functions). 我注意到,对于基本任务,我的服务层方法将与业务层方法完全相同(即“传递”函数)。 What I'm hoping is that this abstraction will be helpful for more complex tasks which may require calls to multiple business layer methods. 我希望这个抽象将有助于更复杂的任务,这些任务可能需要调用多个业务层方法。 Would it just be better to include business logic in the service layer? 将业务逻辑包含在服务层中会更好吗?

From a quick glance, I don't think your service and controller/core layer should have the db context injected into them in this manner. 从快速浏览一下,我不认为您的服务和控制器/核心层应该以这种方式将db上下文注入其中。 They don't actually directly depend on it and doing it in this manner causes some coupling that is not ideal. 它们实际上并不直接依赖它,并且以这种方式进行它会导致一些不理想的耦合。 The core layer should have the user service injected and the user service and BLL should have the repository injected. 核心层应该注入用户服务,用户服务和BLL应该注入存储库。 The repository should have the dbcontext injected by your DI framework and not passed in as a dependency. 存储库应该具有由DI框架注入的dbcontext,而不是作为依赖项传入。

Why are you using dependency injection when you are creating dependencies directly in the service? 当您直接在服务中创建依赖项时,为什么使用依赖项注入?

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

Btw. 顺便说一句。 why are you using so many layers when they actually do nothing? 为什么你在实际上什么都不做的时候会使用这么多层? Your example code just shows that using context in controller directly would produce the same result without three wrapper useless layers. 您的示例代码只显示直接在控制器中使用上下文将产生相同的结果,而没有三个包装器无用的层。 It may be just problem of your example but each layer should bring some added logic. 这可能只是你的例子的问题,但每一层都应该带来一些额外的逻辑。 If you just use it to call something on lower layer you are most probably overarchitecting your code. 如果您只是用它来调用较低层的内容,那么您很可能会对代码进行过多的构建。 This is called onion architecture. 这被称为洋葱建筑。 That is also a reason why it is not a bad practice to add layer once you need it - not upfront. 这也是为什么在需要时添加图层并不是一个不好的做法 - 而不是提前。

Please check this out: http://www.primaryobjects.com/CMS/Article122.aspx EF Repository pattern + Unit Of Work pattern. 请查看: http//www.primaryobjects.com/CMS/Article122.aspx EF存储库模式+工作单元模式。 As for your other layers, it really depends on the application and what it needs to accomplish. 至于你的其他层,它实际上取决于应用程序以及它需要完成的任务。 Please provide more details on what you're trying to do. 请提供您正在尝试做的更多详细信息。

Some of the improvements in organizing projects and design of the layers can be done by focusing on getting the Domain objects correct. 组织项目和层设计的一些改进可以通过专注于使Domain对象正确来完成。

You said you have simple POCO objects as Domain, but the Domain objects should be the one having all the "State and behaviour" of the business. 您说您有简单的POCO对象作为域,但Domain对象应该是具有业务的所有“状态和行为”的对象。 That means you do not need to have BLL and Domain assemblies separate. 这意味着您不需要将BLL和域程序集分开。 Once the Domain objects are defined, EF can be used to create the context and entity classes (which are not Domain classes unless there is no additional behaviour compared to your domain object, but still having them different might be good for future requirements). 一旦定义了Domain对象,就可以使用EF来创建上下文和实体类(除非与域对象相比没有其他行为,但它们不是Domain类,但仍然使它们不同可能对将来的要求有利)。

Other minor point is, I think having interfaces distributed within the Domain and Services layer is better in terms of anyone understanding each layer in isolation. 另一个小问题是,我认为在域和服务层中分布的接口在任何人理解每个层时都更好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在n层体系结构中将Entity Framework模型类与Business Layer类映射 - ASP.NET-MVC - How to map Entity Framework model classes with Business Layer class in n-tier architecture - ASP.NET-MVC 在Web API,实体框架中使用n层体系结构时,数据访问层中的上下文为null - Context is null in Data Access Layer when using n-tier architecture in Web API, Entity Framework 实体框架在N层架构中不起作用 - Entity Framework is not working in N-Tier Architecture 具有n层架构的实体框架5 - Entity Framework 5 with n-Tier Architecture 使用实体框架5代码优先和POCO实现N层数据层? - N-Tier Data Layer implementation with Entity Framework 5 Code-First and POCOs? C#中的实体和N层体系结构 - Entity and N-Tier architecture in C# N层架构中的服务层和业务层之间有什么区别 - What is difference between a service Layer and Business Layer in N layered architecture C#N层架构-BL或表示层是否应了解DataLayer中的自定义类型 - c# N-tier architecture - should the BL or presentation layer know about custom types in DataLayer 是否有必要为n层体系结构中的每个单层编写单元测试代码? - Is it necessary to code unit tests for every single layer on an n-tier architecture? 实体框架的N层应用 - N-Tier Application With Entity Framework
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM