2016-12-05 6 views
3

Я разрабатываю приложение .NET мульти уровневого с использованием репозиторием шаблона. Уровень доступа к данным, который реализует шаблон репозитория, имеет методы, которые возвращают данные на уровень уровня сервиса, который, в свою очередь, возвращает данные на уровень веб-api. В настоящее время я написал методы, которые возвратят либо информацию Клиента, либо информацию о заказе. Мне также нужно написать методы, которые будут возвращать информацию CustomerOrder. Я думаю, что лучше всего написать его на уровне сервиса, но не уверен, как это сделать. Я создал объект DTO на уровне сервиса, который содержит поля как класса Customer, так и Order. Является ли сервисный уровень лучшим местом для написания этой логики. Я думаю, что мне нужно будет заполнить объект Dto на уровне сервиса и вернуть этот объект на уровень представления. Может ли кто-нибудь показать мне дорогу.объекта Return DTO, который содержит более одного объект из сервисного слоя

Entity слой

public class Customers 
    { 


     public int Id { get; set; } 
     public string FirstName { get; set; } 
     public string LastName { get; set; } 
     public Gender Gender { get; set; } 
     public string Email { get; set; } 

     public Address Address { get; set; } 

     public int AddressId { get; set; } 


     public ICollection<Orders> Orders { get; set; } 

    } 
    public class Orders 
    { 
     public int Id { get; set; } 

     public DateTime? OrderDate { get; set; } 
     public int? OrderNumber { get; set; } 

     public Customers Customers { get; set; } 

     public int CustomerId { get; set; } 

     public ICollection<ProductOrder> ProductOrders { get; set; } 
    } 

    public class Address 
    { 
     public int Id { get; set; } 

     public string Address1 { get; set; } 

     public string Address2 { get; set; } 

     public string City { get; set; } 

     public State State { get; set; } 

     public int StateId { get; set; } 


     public ICollection<Customers> Customers { get; set; } 


     public string ZipCode { get; set; } 
    } 

DataAccess Слой

public class CustomerRepository : RepositoryBase<Customers>, ICustomerRepository 
    { 
     public CustomerRepository(IDbFactory dbFactory) 
      : base(dbFactory) { } 



     public IEnumerable<Customers> GetAllCustomers() 
     { 
      return (from customer in this.DbContext.Customers 
        select customer).ToList(); 
     } 

    } 

    public interface ICustomerRepository : IRepository<Customers> 
    { 
     IEnumerable<Customers> GetAllCustomers(); 

    } 


public class OrderRepository : RepositoryBase<Orders>, IOrderRepository 
    { 
     public OrderRepository(IDbFactory dbFactory) 
      : base(dbFactory) {} 

     public IEnumerable<Orders> GetAllOrders() 
     { 
      return (from order in this.DbContext.Orders 
        select order).ToList(); 
     } 

    } 

    public interface IOrderRepository : IRepository<Orders> 
    { 
     IEnumerable<Orders> GetAllOrders(); 
    } 

Сервис слой

public interface ICustomerService 
     { 
      IEnumerable<Customers> GetCustomers(); 
     } 

     public class CustomerService : ICustomerService 
     { 
      private readonly ICustomerRepository _customerRepository; 
      private readonly IUnitOfWork _unitOfWork; 

      public CustomerService(ICustomerRepository customerRepository, IUnitOfWork unitOfWork) 
      { 
       this._customerRepository = customerRepository; 
       this._unitOfWork = unitOfWork; 
      } 


      public IEnumerable<Customers> GetCustomers() 
      { 
       return _customerRepository.GetAll(); 
      } 




public interface IOrderService 
     { 
      IEnumerable<Orders> GetOrders(); 

     } 

     public class OrderService : IOrderService 
     { 
      private readonly IOrderRepository _orderRepository; 
      private readonly IUnitOfWork _unitOfWork; 

      public OrderService(IOrderRepository orderRepository, IUnitOfWork unitOfWork) 
      { 
       this._orderRepository = orderRepository; 
       this._unitOfWork = unitOfWork; 
      } 
      } 

      public IEnumerable<Orders> GetOrders() 
      { 
       return _orderRepository.GetAll(); 
      } 
      } 

Dto объект в слое службы

public class CustomerDto 
    { 
     public int Id { get; set; } 
     public string FirstName { get; set; } 
     public string LastName { get; set; } 
     public string Gender { get; set; } 
     public string Email { get; set; } 

    } 



public class OrderDto 
{ 
    public int Id { get; set; } 
    public DateTime? OrderDate { get; set; } 
    public int? OrderNumber { get; set; } 
} 
public class CustomerOrderDto 
{ 
    public CustomerDto Customer { get; set; } 
    public OrderDto Order { get; set; } 

} 

Mapping (Домен возражает DTO) в сервисном слое

public class DomainToDtoMapping : Profile 
{ 
    public override string ProfileName 
    { 
     get { return "DomainToDtoMapping"; } 
    } 

    [Obsolete] 
    protected override void Configure() 
    { 
     CreateMap<Customers, CustomerDto>(); 
     CreateMap<Address, AddressDto>(); 
     CreateMap<Orders, OrderDto>(); 
     CreateMap<OrdersDetails, OrderDetailsDto>(); 
     CreateMap<State, StateDto>(); 


     CreateMap<CustomerDto, CustomerOrderDto>(); 
     CreateMap<AddressDto, CustomerOrderDto>(); 
     CreateMap<OrderDto, CustomerOrderDto>(); 
     CreateMap<OrderDetailsDto, CustomerOrderDto>(); 
     CreateMap<State, CustomerOrderDto>(); 

    } 
} 
+0

В идеале ваш сервисный уровень будет возвращать только DTO, и вы бы использовали, скажем, Automapper для привязки объектов базы данных к DTO. Теперь вы можете развить сервисный интерфейс независимо от уровня базы данных и объединить объекты базы данных в DTO для возврата из уровня сервиса. –

+0

Помимо сложности, вопрос в том, что вы получаете с помощью дополнительного хранилища репозитория ... –

+0

Человек, вам действительно нужен MediatR. Все эти объекты слоя не приносят вам никаких преимуществ со всем этим. Свернуть эти слои! https://vimeo.com/131633177 –

ответ

0

Попробуйте это:

public interface IOrderService 
    { 
     IEnumerable<CustomerOrderDto> GetOrders(); 
    } 

public IEnumerable<CustomerOrderDto> GetOrders() 
    { 
     List<CustomerOrderDto> customerOrderList = new List<CustomerOrderDto>(); 

     foreach (var item in customerOrderList) 
     { 
      CustomerOrderDto customerOrder = new CustomerOrderDto(); 
      //fields mapping 

      customerOrderList.Add(customerOrder); 
     } 


     return customerOrderList; 
    } 

лучший метод для отображения это linq или this.You не следует использовать Automapper, потому что это так медленно.

+0

Как отобразить объект Customer, Order, Address для CustomerOrderDTO здесь – Tom

+0

Создайте dto для каждого объекта и выполните сопоставление. – codelover

+0

Я обновил сообщение, чтобы показать использование AutoMapper. Какая польза от AutoMapper, если он медленный. Я вижу много людей, рекомендующих AutoMapper. – Tom

0

Вы рассматривали реализацию Composite Pattern?

Ваш CustomerOrderDto будет содержать CustomerDto и класс OrderDto. Как так:

public class CustomerOrderDto 
{ 
    public CustomerDto Customer {get; set;} 
    public OrderDto Order {get; set;} 
} 

Реализация этого шаблона даст следующие преимущества:

  1. Любые будущие изменения в CustomerDto или OrderDto автоматически частью CustomerOrderDto.
  2. Код для отображения данных к dto классов могут быть повторно использованы для отображения одного dto субъекта, а также `CustomerOrderDto».

Код для сопоставления классов Entity классам DTO должен находиться на вашем уровне обслуживания.

Картирование объект клиента к CustomerDto лица:

internal static CustomerDto Map(Customer entity) 
    { 
     if (entity == null) throw new ArgumentNullException("entity"); 

     CustomerDto dto = new CustomerDto(); 
     try 
     { 
      dto.Id = entity.Id; 
      dto.FirstName = entity.FirstName; 
      dto.LastName = entity.LastName; 
      dto.Gender = entity.Gender; 
      dto.Email = entity.Email; 
     } 
     catch (Exception e) 
     { 
      string errMsg = String.Format("Map(entity). Error mapping a Customer entity to DTO. Id: {0}.", entity.Id); 
      //LOG ERROR 
     } 

     return dto; 
    } 

Вы завершили слой хранилища для извлечения объектов Composite CustomerOrder? Я вижу, что у вас есть заполненный код репозитория для GetAllCustomers() и GetAllOrders().

+0

Итак, вы имеете в виду использование составного шаблона, я могу просто создать метод в классе службы, который вернет этот CustomerOrderDto, и automapper позаботится о сопоставлениях – Tom

+0

Как я буду заполнять этот DTO, прежде чем отправить его на уровень презентации – Tom

+0

Таким же образом вы заполняете сущности 'CustomerDto' и' OrderDto' сегодня. Вы просто отправляете каждый класс в соответствующую функцию сопоставления. Мне может быть что-то не хватает, но я не вижу двух методов сопоставления в вашем вопросе. Если вы можете добавить их (или указать их мне, если они уже есть), я бы смог ответить на ваш вопрос более конкретно. –