[英]WCF ServiceKnownType design issue
I'm designing a new solution that will consist of three projects: 我正在设计一个新的解决方案,其中包括三个项目:
"Server" - a WCF service “服务器”-WCF服务
"Client" - a winforms app that will call the WCF service “客户端”-将调用WCF服务的Winforms应用程序
"ServiceContract" - a class lib containing some base classes plus the WCF service contract (interface). “ ServiceContract”-一个类库,其中包含一些基类以及WCF服务协定(接口)。 This will obviously be referenced by the Server, and also by the Client (I'm using a ChannelFactory
rather than have VS generate a service reference). 显然,这将由服务器以及客户端进行引用(我使用ChannelFactory
而不是让VS生成服务引用)。 The service contract looks something like this:- 服务合同如下所示:-
[ServiceContract]
[ServiceKnownType("GetCommandTypes", typeof(CommandTypesProvider))]
public interface INuService
{
[OperationContract]
bool ExecuteCommand(CommandBase command);
}
It's a very basic operation - the client creates a "command" object and sends it to the server to be executed. 这是非常基本的操作-客户端创建一个“命令”对象并将其发送到服务器以执行。 There will be many different commands, all inheriting from CommandBase
(this base class resides in the "ServiceContract" project). 将有许多不同的命令,所有命令均从CommandBase
继承(此基类位于“ ServiceContract”项目中)。 As I'm using the base class in the WCF operation signature, I have to specify the known types which I'm doing dynamically using the ServiceKnownType
attribute. 当我在WCF操作签名中使用基类时,必须使用ServiceKnownType
属性指定要动态执行的已知类型。 This references a helper class ( CommandTypesProvider
) that returns all types deriving from CommandBase
. 这引用了一个帮助程序类( CommandTypesProvider
),该类返回所有从CommandBase
派生的类型。
I've created a simple proof of concept with a couple of derived command classes that reside in the "ServiceContract" project. 我使用驻留在“ ServiceContract”项目中的几个派生命令类创建了一个简单的概念证明。 The helper class therefore only has to reflect types in the executing assembly. 因此,帮助程序类仅需要在执行的程序集中反映类型。 This all works fine. 这一切都很好。
Now in my "real" solution these command classes will be in different projects. 现在,在我的“实际”解决方案中,这些命令类将位于不同的项目中。 These projects will reference the ServiceContract project, rather than vice-versa, which makes it difficult (or impossible?) for the helper to reflect the "command" assemblies. 这些项目将引用ServiceContract项目,而不是相反,这将使助手很难(或不可能?)反映“命令”程序集。 So my question is, how can I provide the known types? 所以我的问题是,如何提供已知类型?
Options I've thought about:- 我考虑过的选项:-
AppDomain.CurrentDomain.GetAssemblies()
, but this fails because the "command" assemblies are not all loaded (I could force this by referencing a type in each, but that doesn't feel right - I want it to be a dynamic, pluggable architecture, and not have to modify code whenever I add a new command project). 我的助手可以通过AppDomain.CurrentDomain.GetAssemblies()
反映,但这失败了,因为“命令”程序集并未全部加载(我可以通过在每个程序集中引用一个类型来强制这样做,但这感觉不对-我希望它能够是一个动态的,可插入的体系结构,并且每次添加新的命令项目时都不必修改代码)。 Any ideas greatly appreciated! 任何想法,不胜感激! Is it something that can be achieved or do I need to rethink my architecture?! 这是可以实现的,还是我需要重新考虑我的体系结构?
Thanks in advance. 提前致谢。
One thing to consider is using the DataContractResolver. 要考虑的一件事是使用DataContractResolver。
Few resources: 很少资源:
WCF Extensibility – Data Contract Resolver by Carlos WCF可扩展性– Carlos的数据合同解析器
Building Extensible WCF Service Interfaces With DataContractResolver by Kelly 由Kelly 使用DataContractResolver构建可扩展的WCF服务接口
Configuring Known Types Dynamically - Introducing the DataContractResolver by Youssef 动态配置已知类型-Youssef引入DataContractResolver
Thanks for the replies regarding the Data Contract Resolver guys. 感谢您有关数据合同解决者的答复。 I probably would have gone down this route normally but as I was using Windsor I was able to come up with a solution using this instead. 我可能通常会走这条路线,但是当我使用Windsor时,我能够提出一个使用此解决方案的解决方案。
For anyone interested, I added a Windsor installer ( IWindsorInstaller
) to each of my "command" projects, which are run using Windsor's container.Install(FromAssembly.InDirectory...
. These installs are responsible for registering any dependencies needed within that project, plus they also register all the command classes which my known types helper can resolve from the container. 对于感兴趣的任何人,我都向我的每个“命令”项目中添加了一个Windsor安装程序( IWindsorInstaller
),这些项目使用Windsor的container.Install(FromAssembly.InDirectory...
来运行。这些安装负责注册该项目中所需的任何依赖项,另外,它们还注册了我的已知类型帮助程序可以从容器中解析的所有命令类。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.