如何将项目分为三层?

时间:2013-12-11 17:15:16

标签: asp.net domain-driven-design data-access-layer n-tier-architecture organization

我有一个asp.net网站,我想把它整理成三层

  1. 数据访问
  2. UI
  3. 这些层中的具体内容是什么?

    e.g

    数据 - 楷模 - 存储库?那只是接口吗? - IoC?

    域 - 服务?

    UI - javascript - 特定区域型号? - css

    有人可以提供一个简单的指南来组织这样的asp.net网站吗?

1 个答案:

答案 0 :(得分:5)

正如其他人所说,每种情况都不同,但对于基本架构,我可能会赞同这样的事情。它让我摆脱了几次堵塞,并且很快就开始运行。

enter image description here

基础设施层

这是完成所有数据访问的地方。数据库连接管理等 存储库包括对数据库的所有查询。 依赖性解决方案也在这里。使用您选择的DI容器。

域层

这是您所有业务逻辑的所在。 域服务接口是UI层调用以使用业务逻辑的

UI

很明显这个......

代码示例

- UI

public class MyController
{
     private readonly IMySerivce _myService;
     public MyController(IMySerivce myService)
     {
         _mySerivce = myService;
     }
     public void MyAction()
     {
         _myService.DoSomeAction();
     }
}

- 域

 public Interface IMyService()
 {
      void DoSomeAction();
 }
 public class MySerivce : IMyService()
 {
      private readonly IMyRepository _myRespository;
      public MySerivce(IMyRepository myRepository)
      {
           _myRepository = myRepository;
      }
      public void DoSomeAction()
      {
           _myRepository.Save();
      }
 }

 public interface IMyRepository
 {
     void Save();
 }

- 数据层

public MyRepository : IMyRepository
{
      public void Save()
      {
          //Manage Save here
      }
}

此外,我通常还有一个单独的区域用于单元/集成测试。

更新

这绝对取决于你的情况。如果没有完全理解你最终要构建的内容,很难说哪种方法最好。

从下面的列表中,您可以看到哪种方法适合您,或者适合您的架构。

无论您选择哪一个,您的Repository Implementation都必须依赖您的Domain Objects项目。

这样做的一些技巧包括:

  • 无映射

您的域对象确实会成为表格的虚拟映射。即在数据库中有一个表调用User。然后有一个名为User的域对象。这是迄今为止最简单的技术。

enter image description here

- 域

public class User
{
    public int Id {get; set;}
    public string UserName {get; set;}
    public string FirstName {get; set;}
    public string LastName {get; set;}
    public string Password {get; set;}
}

- 基础设施

public class UserRepository : IUserRepository
{
     public Core.User GetById(int id)
     {
          return DBConnection.GetByIdQuery(id);
     }
}
  • 映射

Martin Fowler描述了它here

您的基础架构层中可以使用代表数据库表的域传输对象(DTO)。与上面类似,一个名为User的表,一个名为User的DTO。两者都具有相同的属性。

您的域实体将成为您的域和业务逻辑的真实代表。 DTO到您的域实体(搜索查询)的映射可以在存储库中完成,您的域实体到DTO(保存/更新查询)的映射也可以在您的存储库中完成。

要进行映射,您可以创建自定义映射类或使用第三方工具,如AutoMapper。我是AutoMapper的忠实粉丝。

示例代码示例如下:

- 自定义映射器

public class UserRepository : IUserRepository
{
    private readonly IUserMapper _userMapper;
    public UserRepository(IUserMapper userMapper)
    {
         _userMapper = userMapper;
    }
    public Domain.User GetUserById(int id)
    {
         var DtoUser = GetUserByIdQuery(int id);
         return _userMapper.MapUserDTOToDomainEntity(DtoUser);
    }
}
public class UserMapper : IUserMapper
{
     public Domain.User MapUserDTOToDomainEntity(DataEntity.User dtoUser)
     {
          //Manual property mapping
     }
}

- AutoMapper示例

public class UserRepository : IUserRepository
{
    public Domain.User GetUserById(int id)
    {
         var DtoUser = GetUserByIdQuery(int id);
         return Mapper.Map<Domain.User>(DtoUser);
    }
}

其他例子包括:

https://stackoverflow.com/questions/14724612

在博客中有很多辩论,在这里关于DTO的价值, 包括MSDN,此blog和这些https://stackoverflow.com/questions/11237946https://stackoverflow.com/questions/15148866