架构问题:我应该在哪个组件中放置哪个类,以获得干净的解决方案?

2 c# architecture s#arp-architecture

前言:

这是迄今为止我离开这里的最长的帖子......但我认为在这种情况下需要它.

我很长一段时间对这些事情都有疑问:如何命名程序集,以及如何在其中划分类.

我想在这里给出一个应用程序的示例,只有最少的类来演示我正在尝试理解的内容.

想象一下这个应用程序

  • 接受客户端消息,将它们存储在数据库中,然后将它们出列到MTA服务器.
  • 它是一个Web应用程序,具有用于编写消息的ASP.NET接口+附加附件.
  • 还有一个Silverlight客户端,因此webapp使用一个OperationContract(SaveMessage)公开ClientServices WCF ServiceContract.
  • 还有一个Windows客户端......与Silerlight合同做同样的事情.

好.这应该是一个虚假的场景来证明我的无知.

以上将需要以下类:

  • 信息
  • MessageAddress
  • MessageAddressType(包含From,To的枚举)
  • MessageAddressCollection

  • MessageAttachment

  • MessageAttachmentType
  • MessageAttachmentCollection

  • MessageException

  • MessageAddressFormatException

  • MessageExtensions(Message的静态扩展)

  • 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客户端收到的序列化消息,并将它们保存到数据库中.

插件

接下来我会意识到我希望这些对象可以通过第三方插件(例如,病毒检查程序)处理服务器端...

但是插件应该只读取(仅)访问变量以检查变量,如果他们看到他们不喜欢的东西就抛出错误.

所以我会考虑回到从IMessageReadOnly继承Message ...但是在哪里放置那个接口?

Project.Interfaces.dll

如果我把它放在一个名为Project.Interfaces.dll的程序集中,这对于可以引用它但没有引用Contracts.dll的插件有效...但是现在客户端必须引用Contracts程序集和接口...听起来不是一个好方向......

重复对象

或者,我可以有两个Messages结构(并复制其他MessageAttachment等类)...一个用于从客户端到服务器(在Contracts.dll中)进行通信,然后使用第二个ServerMessage/ServerMessageAddress/ServerMessageAddressCollection服务器端,继承自IMessageReadOnly,然后看起来我更接近我想要的.对于重复的对象,插件在访问方面受到限制,而Server BL等对与其工作相关的类型具有完全访问权限,而客户端具有不同但相同的对象...实际上......我们应该开始考虑它们作为不相同的,让我更清楚的是,对象只是在那里与客户交谈,即合同/ Comm对象)......

网站用户界面

如果有两个不同的消息,它们现在有不同的属性...哪一个最适合用于支持ASP.NET表单?ServerMessage对象看起来最快(类型之间没有映射)......但是所有逻辑都已经针对客户端消息对象(具有不同的属性和内部逻辑)进行了解决.那么我是否会使用ClientMessage,并将其映射到Servermessage,以使各种UI逻辑在不同的介质中保持相同?或者我应该更喜欢映射,只是重写UI验证?

那么第三种情况,Silverlight ...... Contracts程序集是一个完整框架程序集... Silverlight无法引用(不同的框架/构建机制)....所以我在Silverlight端的程序集可能是完全相同的代码,但必须是一个不同的程序集.这怎么办?

究竟要考虑什么作为DataContract?

最后......我发誓,接近我的大问题的结尾......那些不太明显DataContract的讨厌的额外课程怎么样?

例如,MessageAddress是一个DataContract.好.它暴露的枚举是它的一部分......有道理......但是如果messageAddress构造函数引发MessageAddressFormatException ...它是否被认为是DataContract的一部分?

服务器,客户端和插件都可以使用通用的类吗?

或者它是BOTH ServerMessageAddress和ClientMessageAddress常见的异常,因此不应该重复,而是在Common程序集中......所以最终,客户端必须绑定到Contracts AND Common?(我们不是只用接口组件走下这条小巷吗?)

常见的基类/接口怎么样?

这些例外应该有共同的基类吗?例如... ClientMessageAddressException,ServerMessageAddressException,ServerMessageVirusException(来自插件)...我应该努力让它们 - 尽可能最好 - 所有都来自一个抽象的MessageException ......或者是有时间当enheritence/reusse只是不再适合争取的目标?

非常感谢您阅读本报告.

我是一名开发人员,在技术方面,我可以随心所欲......但是这些问题,我必须布置组件,架构,我自己,让我非常困惑......而且失去了我太多时间了,因为我自己开车捣乱,把东西从一个组件移动到另一个组件,看看哪一个是最合适的,虽然不是很确定我在做什么,并且试图不进行循环引用......

所以 - 真的 - 感谢您的倾听,我希望这些人能够描述如何干净地展示上述内容,并希望表达如何通过它来思考未来的项目.

Joh*_*ers 6

在花了10分钟编辑格式化问题之后,我仍然会对它进行投票.有没有办法,我会读了这一切.

去拿一份


框架设计指南:可重用.NET库的约定,惯用语和模式(第2版)