Дополнительной осью структуры, которую следует учитывать в решении, является набор прикладных уровней. Например, кажется, что в этом случае у вас есть уровень представления (реализованный с использованием Prism / WPF), уровень обслуживания (реализованный WCF) и уровень бизнеса / домена (реализованный с использованием DDD).
Есть ли способ реструктурировать вещи так, чтобы наш доменный сервис не
технологии зависит?
Если контроллер выполнения теста является контроллером в смысле MVC, то он не должен содержать бизнес-логику. Вместо этого его работа заключается в координации взаимодействия между пользовательским интерфейсом и бизнес-уровнем. В этом конкретном случае контроллер должен направлять команды на бизнес-уровень через уровень обслуживания, реализованный в WCF. Однако сам контроллер является частью уровня представления, и поэтому тот факт, что он зависит от конкретного технологического компонента, такого как агрегатор событий, не является проблемой, поскольку вы уже выбрали WCF / Prim в качестве технологии для уровня представления - нет смысла абстрагироваться, особенно преждевременно.
У нас есть интерфейсы в домене и на стороне WCF, которые в основном
имеют одинаковые имена методов. Есть ли лучший / более чистый способ сделать это?
Обычно этот тип иерархии двойного класса возникает, когда бизнес-уровень DDD представляется как служба через WCF, поскольку вы создаете DTO (контракты данных), которые сопоставляются с сущностями и значениями домена. У DTO нет поведения, их главная роль - представлять данные, поступающие и выходящие из службы. Много раз DTO будет выглядеть очень похоже на соответствующий объект домена, и допустимо иметь это дублирование. Если это по-прежнему вызывает беспокойство, вы можете обратиться к библиотеке отображений, такой как AutoMapper .
Что касается организации решений, у вас есть несколько вариантов. Один из них - полностью скрыть уровень домена от уровня представления и разрешить доступ к нему только через уровень обслуживания. Таким образом, проект уровня представления (WPF / Prism) будет ссылаться на тонкий проект, который содержит контракт на обслуживание и связанные контракты на данные (DTO). Это может быть небольшой проект, который определяет «схему» вашего сервисного уровня. На этот проект также будет ссылаться проект WCF, который реализует контракт на обслуживание. Преимущество этого подхода состоит в том, что домен полностью инкапсулирован уровнем обслуживания. Вы можете изменить реализацию контракта на обслуживание, повторно развернув свой сервис - не нужно также повторно развертывать уровень представления. Недостатком является то, что это может быть излишним или может не подходить для домена, чтобы быть представленным в качестве службы.
Кроме того, меня немного смущают ваши соглашения об именах и структура. Например, GammaCounterProxy не является прокси, прокси создается WCF, когда вы получаете ссылку на сервисный контракт IGammaCounterService. Сам класс, реализующий сервис, является просто реализацией, а не прокси. Кроме того, для GammaCounter кажется неправильным наследовать от GammaCounterProxy. Для GammaCounter было бы разумнее напрямую реализовать IGammaCounter и использовать этот объект в GammaCounterProxy (переименованном во что-то вроде GammaCounterImpl). Работа GammaCounterImpl заключается в обработке некоторой команды (представленной параметрами DTO). Это будет сделано путем загрузки всех соответствующих объектов домена, таких как GammaCounter, вызова методов для них, а затем, возможно, возврата результата (в виде DTO), который затем будет обработан на уровне представления.