Объекты передачи данных - сделать отображение в DTO или в бизнес-объекте?
У меня есть служба WCF, и я только что создал DTO для бизнес-объекта.
Мой вопрос, где поставить сопоставление между двумя?
А) В ДТО?
public class PersonDTO
{
[DataMember] public string Id { get; set; }
[DataMember] public string Name { get; set; }
public void CloneFrom(Person p)
{
Id = p.Id;
Name = p.Name;
}
public void Populate(Person p)
{
p.Id = Id;
p.Name = Name;
}
}
или же
Б) В бизнес-объекте?
public class Person
{
public string Id { get; set; }
public string Name { get; set; }
public void CloneFrom(PersonDTO dto)
{
Id = dto.Id;
Name = dto.Name;
}
public PersonDTO GetDTO()
{
return new PersonDTO()
{
Id = Id;
Name = Name;
}
}
}
Мне нравится разделение проблем в A (бизнес-объект не знает о DTO), но я предпочитаю инкапсуляцию B (нет необходимости раскрывать внутренности бизнес-объекта для DTO).
Просто интересно, был ли стандартный способ?
3 ответа
Я думаю, что это требует отдельного класса, поскольку ни BO, ни DTO не должны заниматься их преобразованием в другой класс.
Я лично использую библиотеку automapper для трансформации объектов. С помощью простых преобразований, как в вашем примере, отображение выполняется в одной строке кода, сложные преобразования также легко настраиваются.
Если вы хотите отобразить себя, вы все равно можете использовать методы расширения, чтобы отделить реализацию отображения от ваших классов DTO и BO.
Я бы предложил компонентный слой. Он должен отвечать за связь между вашим бизнес-уровнем и уровнем данных. В этом случае вы можете использовать его для перевода ваших DTO-объектов в Business Objects.
Вы обеспокоены тем, что "нет необходимости раскрывать внутренности бизнес-объектов для DTO", кажется немного необоснованным, если только в вашем коде нет чего-то, что вы не показываете, так как обращаетесь к общедоступным свойствам, т.е.
Кроме того, вместо методов клонирования вы могли бы вместо этого реализовать оператор приведения: MSDN
Таким образом, вы можете сделать что-то вроде: Person p = (Person)myPersonDTO;