【问题标题】:ASP.NET MVC service layer input output dataASP.NET MVC 服务层输入输出数据
【发布时间】:2013-11-13 05:58:42
【问题描述】:

我在我的项目中使用服务层遵循存储库模式。 我将为每个视图创建一个视图模型。

我感到困惑的是,服务层应该直接访问域对象并将它们返回给控制器,还是应该使用 DTO。如果我应该使用 DTO,应该将它们放在项目架构中的什么位置?

谢谢。

【问题讨论】:

    标签: asp.net-mvc repository-pattern dto service-layer


    【解决方案1】:

    服务层负责通过实现正确的business logic来映射(转换)Dto对象和Domain对象。

    您的 DTO 对象应在控制器和服务中使用。

    DTO 在 Controller 和 Service 之间传输,而 Domain 对象在 Service 和 Repository 之间传输

    Controller 不知道 Domain,Repository 不知道 DTO。 Service 知道 DTO 和 Domain,并使用业务规则将它们相互转换,例如司机和道路之间的汽车,就像你我之间的 stackoverflow,就像一切,抽象......

    以下代码是一个示例。考虑每个命名空间都是一个包。

    namespace Controllers
    {
        using Services;
        using DataTransferObjects;
    
        public class CoffeeController
        {
            public ICoffeeService CoffeeService { get; set; }
    
            public JsonResult GetCoffee(GetCoffeeInDto inDto)
            {
                var result = CoffeeService.GetCoffee(inDto);
                return JsonResult(result);
            }
    
            public JsonResult SaveCoffee(SaveCoffeeInDto inDto)
            {
                var outDto = CoffeeService.SaveCoffee(inDto);
                return JsonResult(outDto);
            }
        }
    }
    
    namespace Services
    {
        using DataTransferObjects;
        public interface ICoffeeService
        {
            GetCoffeeOutDto GetCoffee(GetCoffeeInDto inDto);
            SaveCoffeeOutDto SaveCoffee(SaveCoffeeInDto inDto);
        }
    }
    
    namespace Services.Impl
    {
        using Services;
        using Repository;
        using DataTransferObjects;
        using Domain;
    
        public class CoffeeService : ICoffeeService
        {
            public ICoffeeRepository CoffeeRepository { get; set; }
            public GetCoffeeOutDto GetCoffee(GetCoffeeInDto inDto)
            {
                var entity = CoffeeRepository.Get(inDto.Id);
                return new GetCoffeeOutDto {Id = entity.Id, Name = entity.Name};
            }
    
            public SaveCoffeeOutDto SaveCoffee(SaveCoffeeInDto inDto)
            {
                var entity = new CoffeeEntity {Name = inDto.Name};
                CoffeeRepository.Save(entity);
                return new SaveCoffeeOutDto {Id = entity.Id};
            }
        }
    }
    
    namespace Repository
    {
        using Domain;
        public interface ICoffeeRepository
        {
            CoffeeEntity Get(int id);
            void Save(CoffeeEntity coffeeEntity);
        }
    }
    
    namespace Repository.Impl
    {
        using Repository;
        using Domain;
    
        public class CoffeeRepository:ICoffeeRepository
        {
            public CoffeeEntity Get(int id)
            {
                //get entity from db
                throw new System.NotImplementedException();
            }
    
            public void Save(CoffeeEntity coffeeEntity)
            {
                //insert entity into db
                throw new System.NotImplementedException();
            }
        }
    }
    
    namespace DataTransferObjects
    {
        public class SaveCoffeeInDto
        {
            public string Name { get; set; }
        }
    
        public class SaveCoffeeOutDto
        {
            public int Id { get; set; }
        }
    
        public class GetCoffeeInDto
        {
            public int Id { get; set; }
        }
    
        public class GetCoffeeOutDto
        {
            public int Id { get; set; }
            public string Name { get; set; }
        }
    }
    
    namespace Domain
    {
        public class CoffeeEntity
        {
            public int Id { get; set; }
            public string Name { get; set; }
        }
    }
    

    【讨论】:

    • 如果我将 CoffeeEntity 发送到控制器而不是 GetCoffeeInDto,我是否违反了架构规则?在我看来,重写域对象只是为了利用 DTO。
    • 是的,如果你向控制器发送一个实体,你就违反了架构。但是你不必使用这种架构,如果你的项目不大,业务不够复杂的话。将对象分离为 Dto 和 Entity 是关于信息和数据之间的区别。关于关注点分离原则,在数据层玩数据和在表示层玩信息被认为是单独的关注点,并使用单独的类实现来保持。
    • +1 很好的答案。 @SherleyDev 看看这里:stackoverflow.com/a/21569720/654708 以获得更详细的答案。请注意,将控制器绑定到域模型本身并不是坏事;对于较小的项目,创建 DTO 可能被认为是矫枉过正。
    猜你喜欢
    • 2012-11-01
    • 1970-01-01
    • 2014-02-25
    • 1970-01-01
    • 1970-01-01
    • 2017-01-07
    • 1970-01-01
    • 2011-09-18
    • 2012-01-10
    相关资源
    最近更新 更多