Преамбула:
Это самый длинный пост, который я здесь оставил ... но я думаю, что он необходим в этом случае.
У меня уже давно есть вопросы об этих вещах: как называть сборки и как разделять классы внутри них.
Я бы хотел привести пример приложения здесь с минимальным количеством классов, чтобы продемонстрировать то, что я пытаюсь понять.
Представьте себе приложение, которое
- Принимает клиентские сообщения, сохраняет их в БД, а затем выводит их в очередь на сервер MTA.
- Это веб-приложение, которое имеет интерфейс ASP.NET для написания сообщения + вложения.
- Существует также клиент Silverlight, поэтому веб-приложение предоставляет ClientCervices WCF ServiceContract с одним OperationContract (SaveMessage).
- Есть также клиент Windows ... делает то же самое, что и контракт Silerlight.
OK. Этого должно быть достаточно по поддельному сценарию, чтобы продемонстрировать мою невежественность.
Для вышеупомянутых нужны следующие классы:
- Сообщение
- MessageAddress
- MessageAddressType (перечисление с From, To)
MessageAddressCollection
MessageAttachment
- MessageAttachmentType
MessageAttachmentCollection
MessageException
MessageAddressFormatException
MessageExtensions (статическое расширение для сообщения)
- MessageAddressExtensions (статическое расширение для MessageAddress)
- MessageAttachmentExtensions (статическое расширение для MessageAttachment)
Project.Contract.dll
Моим первым шагом при организации вышеупомянутого в правильные сборки будет наблюдение, что Message, MessageAddress, MessageAttachment, перечисления, необходимые для его свойств (MessageAddressType, MessageAttachmentType) и необходимые для них коллекции (MessageAddressCollection, MessageAttachmentCollection), все в помечать как [DataContract], чтобы их можно было сериализовать между клиентом WCF и сервером.
Будучи общим для обоих, я думаю, что переместил бы их в нейтральную общую сборку под названием Contract.
Project.Client.dll
Мне потребуется клиентский прокси сервера [ServiceContract], который ссылается на классы в Contract.dll.
Так что теперь сервер, который также ссылается на Project.Contract.dll, теперь может сохранять сериализованные сообщения, полученные от клиента WCF, и сохранять их в БД.
Плагины
Далее я бы понял, что хотел бы, чтобы эти объекты обрабатывались на стороне сервера сторонними плагинами (например, средством проверки на вирусы) ...
Но плагины должны иметь доступ к переменным только для чтения, чтобы проверять переменные и выдавать ошибки, если они видят что-то, что им не нравится.
Так что я бы подумал о том, чтобы вернуться к тому, чтобы Message наследовал от IMessageReadOnly ... но где разместить этот интерфейс?
Project.Interfaces.dll
Если я помещу его в сборку под названием Project.Interfaces.dll, это будет работать для плагинов, которые могут ссылаться на это без ссылки на Contracts.dll ... но теперь клиент должен ссылаться как на сборку контрактов, так и на интерфейсы. ... не похоже на хорошее направление ...
Двойные объекты
В качестве альтернативы, я мог бы иметь две структуры сообщений (и дублировать другие классы MessageAttachment и т. Д.) ... одну для связи от клиента к серверу (в Contracts.dll), а затем использовать второй ServerMessage / ServerMessageAddress / ServerMessageAddressCollection на стороне сервера, которая наследуется от IMessageReadOnly, и тогда может показаться, что я ближе к тому, что хочу.
С дублирующимися объектами плагины имеют ограниченный доступ, в то время как Server BL и т. Д. Имеет полный доступ к типам, относящимся к его работе, в то время как у клиента есть разные, но идентичные объекты ...На самом деле ... они, вероятно, мне следует начать рассматривать их как неидентичные, чтобы в моей голове стало ясно, что объекты просто для общения с клиентами, то есть объекты Contract / Comm) ...
Интерфейс веб-сайта
, который вызывает ... гул ... если есть два разных сообщения, и у них теперь разные свойства ... какое из них лучше всего использовать для поддержки форм ASP.NET? Объект ServerMessage кажется самым быстрым (нет сопоставления между типами) ... но вся логика уже проработана с объектами сообщений клиента (с различными свойствами и внутренней логикой). Итак, буду ли я использовать ClientMessage и сопоставлять его с Servermessage, чтобы различные логики пользовательского интерфейса были одинаковыми для разных сред? или я должен предпочесть отображение и просто переписать валидацию пользовательского интерфейса?
А как насчет третьего случая, Silverlight ... Сборка Contracts была сборкой Full Framework ... которую Silverlight не может перефразировать (другой механизм фреймворка / сборки) .... так что сборка, которую я имею на Silverlight сторона может быть точно таким же кодом, но должна быть другая сборка. Как это работает?
Что именно считать DataContract?
Наконец-то ... и это, клянусь, ближе к концу моего огромного вопроса ... как насчет надоедливых дополнительных классов, которые явно не являются DataContract?
Например, MessageAddress был DataContract. Хорошо. И перечисленные в нем перечисления являются его частью ... Имеет смысл ... Но если конструктор messageAddress вызывает MessageAddressFormatException ... считается ли он частью DataContract?
Могут ли быть классы, общие для сервера, клиента и плагинов?
Или это исключение, которое является общим для ОБА ServerMessageAddress и ClientMessageAddress, поэтому не должно дублироваться, а вместо этого находиться в общей сборке ... так что в конце концов клиент должен связываться с контрактами и общими? (Разве мы не пошли по этому переулку с сборкой Интерфейсов?)
А как насчет общих базовых классов / интерфейсов?
И должны ли эти исключения иметь общие базовые классы? например ... ClientMessageAddressException, ServerMessageAddressException, ServerMessageVirusException (из плагина) ... я должен изо всех сил пытаться получить их - как можно лучше - все происходят от абстрактного MessageException ... или есть время, когда наследование / повторное использование просто больше не подходящая цель, к которой нужно стремиться?
ОГРОМНОЕ СПАСИБО ЗА ЧТЕНИЕ ЭТОГО ДАРА.
Я разработчик, и с технической точки зрения я могу сойтись хорошо ... но такие вопросы, где мне приходилось выкладывать сборки, архитектуру, меня самого, оставляют меня в замешательстве ... и теряю меня СОООО, много времени, так как я веду себя бэтти, перемещая вещи из одной сборки в другую, чтобы увидеть, какая из них лучше всего подходит, и при этом не совсем уверен в том, что я делаю, и стараясь не получать круговые ссылки ... .
Так что - действительно - спасибо за прослушивание, и я надеюсь, что это прочитают люди, которые могут описать, как изложить вышеизложенное, и, надеюсь, выразить, как продумать мой путь для будущих проектов.