【发布时间】:2009-07-19 09:50:59
【问题描述】:
序言:
这是迄今为止我在这里留下的最长的帖子......但我认为在这种情况下它是必需的。
长期以来,我一直对这类事情有疑问:如何命名程序集,以及如何在其中划分类。
我想在这里举一个应用程序的例子,只用最少的类来演示我想要理解的内容。
想象一个应用程序
- 接受客户端消息,将它们存储在数据库中,然后将它们出列到 MTA 服务器。
- 它是一个 Web 应用程序,具有 ASP.NET 接口来编写消息和附加附件。
- 还有一个 Silverlight 客户端,因此 web 应用公开了一个 ClientServices WCF ServiceContract,带有一个 OperationContract (SaveMessage)。
- 还有一个 Windows 客户端...与 Silerlight 合同做同样的事情。
好的。这应该足以证明我的无知了。
以上将需要以下类:
-
留言
-
消息地址
-
MessageAddressType(带有 From、To 的枚举)
-
消息地址集合
-
邮件附件
-
消息附件类型
-
MessageAttachmentCollection
-
消息异常
-
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 客户端接收到的序列化消息,并将它们保存到数据库中。
插件
接下来我会意识到我希望这些对象由 3rd 方插件(例如病毒检查器)在服务器端进行处理...
但插件应该对变量具有只读访问权限(仅),以便检查变量,并在看到不喜欢的内容时抛出错误。
所以我会考虑让 Message 继承自 IMessageReadOnly ...但是该接口放在哪里?
Project.Interfaces.dll
如果我把它放在一个名为 Project.Interfaces.dll 的程序集中,这将适用于那些可以在没有引用 Contracts.dll 的情况下引用它的插件......但是现在客户端必须同时引用 Contracts 程序集和接口...听起来不是一个好的方向...
重复对象
或者,我可以有两个 Messages 结构(并复制其他 MessageAttachment 等类)...一个用于从客户端到服务器的通信(在 Contracts.dll 中),然后使用第二个 ServerMessage/ServerMessageAddress /ServerMessageAddressCollection 在服务器端,它继承自 IMessageReadOnly,然后看起来我更接近我想要的。 对于重复的对象,插件的访问受到限制,而服务器 BL 等对其工作相关的类型具有完全访问权限,而客户端具有不同但相同的对象...... 事实上......我可能应该开始将它们视为不相同的,让我更清楚地知道这些对象只是为了与客户交谈,即合同/通信对象)......
网站用户界面
这会带来...嗯...如果有两个不同的消息,并且它们现在具有不同的属性...哪一个最适合用于支持 ASP.NET 表单? ServerMessage 对象似乎最快(类型之间没有映射)......但是所有逻辑都已经针对客户端消息对象(具有不同的属性和内部逻辑)制定出来。那么我是否会使用 ClientMessage,并将其映射到 Servermessage,以跨不同媒体保持各种 UI 逻辑相同?还是我应该更喜欢映射,只重写 UI 验证?
第三种情况呢,Silverlight...Contracts 程序集是一个完整框架程序集...Silverlight 无法引用(不同的框架/构建机制)...所以我在 Silverlight 上的程序集side 可能是完全相同的代码,但必须是不同的程序集。效果如何?
究竟什么是 DataContract?
最后……我发誓,我的大问题快要结束了……那些不明确是 DataContract 的讨厌的额外类呢?
例如,MessageAddress 是一个 DataContract。好的。它公开的枚举是其中的一部分...有道理...但是如果 messageAddress 构造函数引发 MessageAddressFormatException...它是否被视为 DataContract 的一部分?
可以有服务器、客户端和插件通用的类吗?
或者它是 ServerMessageAddress 和 ClientMessageAddress 共有的异常,所以不应该重复,而是在 Common 程序集中......所以最终,客户端必须绑定到 Contracts AND Common? (我们不是带着接口组件沿着这条小路走下去的吗?)
常见的基类/接口呢?
这些异常应该有共同的基类吗?例如...ClientMessageAddressException、ServerMessageAddressException、ServerMessageVirusException(来自插件)...我是否应该努力让它们——尽可能地——都从抽象 MessageException 派生...或者是否有时间继承/reusse只是不再是一个合适的奋斗目标?
非常感谢您阅读本文。
我是一名开发人员,在技术方面我可以应付得来……但是这些问题,我不得不布置程序集、架构,我自己,让我非常困惑……并且浪费了我很多时间,当我开车时,把东西从一个组件移到另一个组件,看看哪个最合适,同时我不确定我在做什么,并试图不得到循环引用。 .
所以 - 真的 - 感谢您的收听,我希望能够描述如何清晰地布置上述内容的人能够阅读这篇文章,并希望能表达我在未来项目中的思考方式。
【问题讨论】:
标签: c# architecture s#arp-architecture