Мой вопрос носит скорее архитектурный характер, меньше связан с реальной реализацией.
Я создал API на основе WCF, но не могу определиться с тем, как отделить PL от BL. Я сделал свой сервис тонким, чтобы он содержал только минимум реализации, что-то вроде:
public TagItemResponse TagItem(TagItemRequest request)
{
return (new ItemTagRequestProcessor()).GetResponse(request);
}
Чем, конечно, возникает первый вопрос, к какому слою принадлежат RequestProcessors? Я думаю, что было бы неправильно называть их фасадом, но в то же время они не имеют ничего общего с презентацией. На данный момент я решил, что они, тем не менее, принадлежат к ЛП. Методы процессора принимают мои DTO (DataContracts) в качестве входных данных, проверяют сообщение запроса (базовый класс), аутентифицируют (базовый класс) и в конечном итоге возвращают один ответ DTO, например:
protected override void Process(TagItemRequest request, TagItemResponse response, Host host)
{
var profile = ProfileFacade.GetProfile(host, request.Profile);
var item = ItemFacade.GetItemId(host, request.Item);
var tags = new List<Tag>();
foreach (var name in request.Tags)
{
var tag = TagFacade.GetTag(profile, name);
ItemFacade.TagItem(item, tag);
tags.Add(tag);
}
ItemFacade.UntagItem(item, tags);
}
Теперь я спрашиваю себя, зачем мне классы фасада 1: 1, связанные с моими бизнес-объектами. Например, у меня есть HostFacade, который действует как слой между hostDAO и процессорами. Однако он содержит очень мало логики, он просто обрабатывает вызовы DAO.
public static Host GetHost(HostDTO dto)
{
return HostDAO.GetHostByCredentials(dto.Username, dto.Password);
}
Вопрос: я мог бы также объединить процессоры и фасады, верно?
Я прочитал много статей / книг по этому вопросу, но я все еще не могу выбрать «правильный» путь и склонен выбирать другой подход каждый раз, когда сталкиваюсь с проблемой. Интересно, существует ли правильный подход?
Я нашел f.ex. пример doFactory, где они общались с классами DAO прямо из реализации сервиса. Мне это не очень нравится, так как большинство методов ServiceContract имеют некоторую логику и, таким образом, хорошо подходят для использования с общими базовыми классами.
Я также нашел другие примеры, когда из сервисов вызываются только фасады, но, похоже, это хорошо работает только для очень мелких сообщений. Мои сообщения «жирные» и составные, чтобы максимально сократить количество обращений в службу. Кажется, моя дополнительная проблема - мой дополнительный слой обработки.
Вероятно, нет единого ответа относительно того, как правильно наложить службу WCF, но, надеюсь, некоторые из вас найдут мнение, которое либо подстроит мои инстинкты, либо прольет для меня новый свет на эту тему. *
Thanx!
Geoffrey