Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/285.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 具有服务层、业务层和实体框架的N层体系结构_C#_Asp.net Mvc_Asp.net Mvc 3_Entity Framework_Asp.net Mvc 2 - Fatal编程技术网

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

C# 具有服务层、业务层和实体框架的N层体系结构,c#,asp.net-mvc,asp.net-mvc-3,entity-framework,asp.net-mvc-2,C#,Asp.net Mvc,Asp.net Mvc 3,Entity Framework,Asp.net Mvc 2,我只是想在我设计应用程序的方式上得到一些反馈/帮助。我当前的解决方案结构如下所示: namespace Core.Controllers { public class HomeController : Controller { private IDbContext dbContext; public HomeController(IDbContext dbContext) { this.dbContext

我只是想在我设计应用程序的方式上得到一些反馈/帮助。我当前的解决方案结构如下所示:

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));
        }
        ...
  • UI(实际的MVC应用程序)
  • 核心(仅控制器和视图模型)
  • 服务
  • BLL
  • 数据(实体框架DbContext,映射到域对象)
  • 域(简单POCO对象)
  • 接口
其他东西

  • Ninject将DbContext注入控制器(每个请求)
  • 自动映射将域对象映射到ViewModel
所有程序集都引用了Interfaces项目,顾名思义,它只不过是简单的接口(即IDbContext、IRepository等)

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

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

控制器示例如下所示:

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));
        }
        ...
名称空间核心控制器
{
公共类HomeController:控制器
{
私有IDB上下文dbContext;
公共家庭控制器(IDbContext dbContext)
{
this.dbContext=dbContext;
}
公共操作结果用户()
{
UserService UserService=newuserservice(dbContext);
var users=userService.GetAllUsers();
返回视图(Mapper.Map(用户));
}
...
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();
        }
        ...
命名空间服务
{
公共类用户服务
{
私有只读IDbContext dbContext;
公共用户服务(IDbContext dbContext)
{
this.dbContext=dbContext;
}
公共IEnumerable GetAllUsers()
{
IRepository userRepository=新存储库(dbContext);
UserBLL UserBLL=新的UserBLL(userRepository);
返回userbl.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();
        }
        ...
名称空间BLL
{
公共类UserBLL
{
私有只读IRepository用户存储库;
公共用户BLL(IRepository用户存储库)
{
this.userRepository=userRepository;
}
公共IEnumerable GetAllUsers()
{
返回userRepository.Get();
}
...

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

当您直接在服务中创建依赖项时,为什么要使用依赖项注入

public IEnumerable<User> GetAllUsers()
{
    IRepository<User> userRepository = new Repository<User>(dbContext);
    UserBLL userBLL = new UserBLL(userRepository);
    return userBLL.GetAllUsers();
}
public IEnumerable GetAllUsers()
{
IRepository userRepository=新存储库(dbContext);
UserBLL UserBLL=新的UserBLL(userRepository);
返回userbl.GetAllUsers();
}

顺便说一句,为什么你要使用这么多的层,而它们实际上什么都不做?你的示例代码只是表明,直接在控制器中使用上下文将产生相同的结果,而不需要三个无用的包装层。这可能只是你的示例的问题,但每一层都应该带来一些附加逻辑。如果你只是使用它来调用较低层上的东西,y您很可能正在对代码进行总体架构。这被称为洋葱架构。这也是为什么在需要时添加层(而不是预先添加层)不是一个坏做法的原因。

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

请检查:EF ReposToury模式+工作单元模式。至于其他层,这实际上取决于应用程序及其需要完成的任务。请提供更多关于您正在尝试执行的任务的详细信息。

组织项目和层设计方面的一些改进可以通过关注正确的域对象来完成

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


另一个次要的问题是,我认为在域和服务层中分布接口会更好,因为任何人都可以孤立地理解每一层。

但大多数应用程序都遵循相同的架构模式。它们只包装底层,示例业务层只包装数据访问层并检查结果但我对实体框架DB优先的方法感到困惑,因为它会生成POCOs(域)和数据访问层。那么我们适合这个.edmx文件的哪一层?@stephen.vakil-你能给出如何做的代码示例吗?我想实现的是,在控制器中,我想使用DI创建biz对象的实例。在biz层中,我想使用DI创建DAL的实例。在ASPCore中如何做?如果我在start中添加上下文对象up.cs,它是否适用于所有类,即使该类在不同的项目中(如业务逻辑的单独项目)。请提供帮助,谢谢。@stephen.vakil您能提供吗