简体   繁体   English

WCF ServiceKnownType设计问题

[英]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:- 我考虑过的选项:-

  • The "Server" and "Client" projects will reference both the "ServiceContract" project and the various "command" projects. “服务器”和“客户端”项目将同时引用“ ServiceContract”项目各种“ command”项目。 My helper could reflect through 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()反映,但这失败了,因为“命令”程序集并未全部加载(我可以通过在每个程序集中引用一个类型来强制这样做,但这感觉不对-我希望它能够是一个动态的,可插入的体系结构,并且每次添加新的命令项目时都不必修改代码)。
  • Specify the known types in config. 在配置中指定已知类型。 Again it would be nice if the app was dynamic, rather than have to update the config each time I add a command class. 同样,如果应用程序是动态的,那将很好,而不是每次添加命令类都必须更新配置。
  • Is there any way to access the underlying DataContractSerializer on both the client and server, and pass it the known types? 有什么方法可以访问客户端和服务器上的基础DataContractSerializer,并将其传递给已知类型? I guess I'll still have the same issue of not being able to reflect the assemblies unless they've been loaded. 我想我仍然会遇到同样的问题,除非它们已经被加载,否则无法反映这些程序集。
  • Refactor things to enable the ServiceContract project to reference the various command projects. 重构事物以使ServiceContract项目能够引用各种命令项目。 I can then reflect them using 'Assembly.GetReferencedAssemblies()'. 然后,我可以使用“ Assembly.GetReferencedAssemblies()”来反映它们。 I guess the various command classes are part of the service contract, so perhaps this is the way to go? 我猜想各种命令类都是服务合同的一部分,那么也许这是要走的路? Edit: looks like this has the same problem of only finding loaded assemblies. 编辑:看起来这与仅查找已加载的程序集具有相同的问题。

Any ideas greatly appreciated! 任何想法,不胜感激! Is it something that can be achieved or do I need to rethink my architecture?! 这是可以实现的,还是我需要重新考虑我的体系结构?

Thanks in advance. 提前致谢。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM