Объекты передачи данных - сделать отображение в 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;

Другие вопросы по тегам