DTO
Я создаю веб-приложение, которое я хотел бы масштабировать для многих пользователей. Кроме того, мне нужно предоставить функции доверенным третьим лицам через веб-службы.
Я использую LLBLGen для создания уровня доступа к данным (с использованием SQL Server 2008). Цель состоит в том, чтобы построить уровень бизнес-логики, который защищает веб-приложение от деталей DAL и, конечно же, обеспечивает дополнительный уровень проверки за пределами DAL. Кроме того, насколько я могу судить сейчас, веб-сервис будет по существу тонкой оболочкой над BLL.
DAL, конечно, имеет свой собственный набор объектов сущности, например CustomerEntity, ProductEntity и т.д. Однако я не хочу, чтобы уровень представления имел доступ к этим объектам напрямую, поскольку они содержат специальные методы DAL, а сборка специфична для DAL и так далее. Таким образом, идея состоит в создании объектов передачи данных (DTO). Идея состоит в том, что это, по сути, простые старые объекты С#/.NET, которые имеют все поля, скажем, CustomerEntity, которые на самом деле являются таблицей базы данных Customer, но ни один другой материал, за исключением, может быть, некоторых свойств IsChanged/IsDirty. Таким образом, были бы CustomerDTO, ProductDTO и т.д. Я предполагаю, что они наследуют базовый класс DTO. Я считаю, что могу сгенерировать их с помощью какого-то шаблона для LLBLGen, но пока не уверен.
Итак, идея состоит в том, что BLL будет раскрывать свою функциональность, принимая и возвращая эти объекты DTO. Я думаю, что веб-служба будет обрабатывать преобразование этих объектов в XML для сторонних пользователей, использующих его, многие из них могут не использовать .NET(также некоторые вещи будут script, вызываемые из вызовов AJAX в веб-приложении, используя JSON).
Я не уверен, как лучше всего это разработать и как продвигаться вперед. Вот некоторые проблемы:
1) Как это должно быть показано клиентам (уровень представления и код веб-службы)
Я думал, что будет один открытый класс, который имеет эти методы, каждый вызов будет атомарной операцией:
InsertDTO, UpdateDTO, DeleteDTO, GetProducts, GetProductByCustomer и т.д....
Затем клиенты просто вызывают эти методы и передают соответствующие аргументы, обычно DTO.
Это хороший, работоспособный подход?
2) Что вернуть из этих методов? Очевидно, методы Get/Fetch возвратят DTO. Но как насчет вложений? Часть подписи может быть:
InsertDTO(DTO dto)
Однако при вставке, что нужно вернуть? Я хочу получать уведомления об ошибках. Тем не менее, я использую автоинкрементные первичные ключи для некоторых таблиц (однако, несколько таблиц имеют естественные ключи, особенно многие-ко-многим).
Один из вариантов, о котором я думал, - это класс Result:
class Result
{
public Exception Error {get; set;}
public DTO AffectedObject {get; set;}
}
Итак, на вставке DTO получит свой идентификатор get ID (например, CustomerDTO.CustomerID) и затем помещает в этот объект результата. Клиент будет знать, есть ли ошибка, если Result.Error!= Null, а затем он будет знать идентификатор из свойства Result.AffectedObject.
Это хороший подход? Одна из проблем заключается в том, что кажется, что он передает много данных назад и вперед, что является избыточным (когда это только идентификатор). Я не думаю, что добавление свойства "int NewID" будет чистым, потому что некоторые вставки не будут иметь такой автоинкрементный ключ. Другая проблема заключается в том, что я не думаю, что веб-службы справятся с этим хорошо? Я считаю, что они просто вернут базовый DTO для AffectedObject в классе Result, а не в производный DTO. Я предполагаю, что могу решить это, имея много разных объектов Result (возможно, полученных из базового Result и наследующего свойство Error), но это не кажется очень чистым.
Хорошо, я надеюсь, что это не слишком многословно, но я хочу быть ясным.