DTO
Я создаю веб-приложение, которое я хотел бы масштабировать для многих пользователей. Кроме того, мне нужно предоставить функциональность доверенным сторонним организациям через веб-службы.
Я использую LLBLGen для создания слоя доступа к данным (с использованием SQL Server 2008). Цель состоит в том, чтобы создать слой бизнес-логики, который защищает веб-приложение от деталей DAL, и, конечно, обеспечить дополнительный уровень проверки помимо DAL. Кроме того, насколько я могу судить прямо сейчас, Web-сервис по сути будет тонкой оболочкой над BLL.
DAL, конечно, имеет свой собственный набор объектов сущностей, например, CustomerEntity, ProductEntity и так далее. Однако я не хочу, чтобы уровень представления имел прямой доступ к этим объектам, поскольку они содержат специфичные для DAL методы, а сборка - для DAL и так далее. Итак, идея заключается в создании объектов передачи данных (DTO). Идея состоит в том, что это будут, по сути, простые старые объекты C # / .NET, которые имеют все поля, скажем, CustomerEntity, которые на самом деле являются таблицей базы данных Customer, но не имеют ничего другого, кроме, возможно, некоторых свойств IsChanged / IsDirty. Таким образом, будут CustomerDTO, ProductDTO и т. Д. Я предполагаю, что они наследуются от базового класса DTO. Я полагаю, что могу сгенерировать их с помощью некоторого шаблона для LLBLGen, но я пока не уверен в этом.
Итак, идея заключается в том, что BLL будет раскрывать свои функциональные возможности, принимая и возвращая эти объекты DTO. Я думаю, что веб-служба будет обрабатывать преобразование этих объектов в XML для третьих сторон, использующих его, многие могут не использовать .NET (также некоторые функции будут вызываться сценариями из вызовов AJAX в веб-приложении с использованием JSON).
Я не уверен, что лучший способ спроектировать это и как двигаться дальше. Вот некоторые проблемы:
1) Как это должно быть открыто для клиентов (уровень представления и код веб-службы)
Я думал, что будет один открытый класс с этими методами, каждый вызов будет атомарной операцией:
Вставить DTO, Обновить DTO, Удалить DTO, 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.ActedObject.
Это хороший подход? Одна проблема состоит в том, что кажется, что он передает много данных назад и вперед, что является избыточным (когда это просто идентификатор). Я не думаю, что добавление свойства "int NewID" было бы чистым, потому что некоторые вставки не будут иметь такой автоинкрементный ключ. Другая проблема в том, что я не думаю, что веб-сервисы справятся с этим хорошо? Я полагаю, что они просто вернут базовый DTO для ActedObject в классе Result, а не производный DTO. Я полагаю, что я мог бы решить эту проблему, имея МНОЖЕСТВО различных типов объектов Result (возможно, полученных из базового Result и унаследовавших свойство Error), но это не кажется очень чистым.
Хорошо, я надеюсь, что это не слишком многословно, но я хочу быть ясным.