抽象类的所有派生类型的 KnownType?
我们有一个抽象类,它是我们通过 WCF 服务发送的许多不同请求的基础。这是一个丑陋而令人发指的黑客行为,每次我们添加一个新请求时,我们都必须记住将 [KnownType]
属性添加到这个基类中。
有没有办法告诉 DataContractSerializer 将此抽象类型的所有派生视为 KnownType
?
We have an abstract class that is the base for a number of different requests we send over a WCF service. It's an ugly heinous hack that every time we add a new request we have to remember to add the [KnownType]
attribute to this base class.
Is there a way to tell the DataContractSerializer
to treat ALL derivations of this abstract type as a KnownType
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我在 WCF 服务中遇到了同样的问题,并执行了以下“不太令人发指”的 hack 来解决已知的类型限制。我概述只是为了显示替代选项,由您决定它是否更好。
在服务启动时,通过反射加载您想要公开的类型。例如,如果所有 WCF 公开的实体都派生自一个公共抽象基(或更多),则从它们应该位于的程序集中加载所有类型。出于性能原因静态缓存这些类型。
创建一个返回上述缓存类型的静态方法,具有以下签名:
public static IEnumerable; GetKnownTypes(ICustomAttributeProviderprovider)
使用以下属性标记 WCF 接口
[ServiceKnownType("GetKnownTypes", typeof(StaticClassThatCachesTypes))]
这应该可以让您自动公开从以下基类派生或将派生的所有类型您的选择,只要未来的开发人员将它们放置在正确的程序集中即可。
I had the same problem in a WCF service and did the following "less heinous" hack to work around the known type limitation. I'm outlining just for the sake of showing alternate options, it's up to you to decide if it's better or not.
At service startup, load via reflection the types you want to expose. E.g. if all your WCF-exposed entities derive from a common abstract base (or more), load all types from the assembly they're supposed to be located into. Cache these types statically for performance reasons.
Create a static method that returns the said cached types, with the following signature:
public static IEnumerable<Type> GetKnownTypes(ICustomAttributeProvider provider)
Mark the WCF interface with the following attribute
[ServiceKnownType("GetKnownTypes", typeof(StaticClassThatCachesTypes))]
This should give you automatic exposing of all types that are or will be derived from the base class(es) of your choice, as long as the future developer(s) place them in the correct assembly.
除了 Dan C. 给出的选项之外,另一种选择是切换到 NetDataContractSerializer - 它不需要已知的类型声明,因为它与确切的合约实现紧密耦合,因此您需要在客户端和服务器之间共享包含类型的程序集 - 并且在这种情况下你肯定会失去互操作性。有一些关于这样做的帖子(我见过 这个经常出现在google/bing结果中)。
Another option in addition to the one given by Dan C. is to switch to the NetDataContractSerializer - it does not require known type declarations, since it is tightly coupled to the exact contract implementation, so you'll need to share the assembly which contains the types between the client and the server - and you'll definitely lose interoperability in this scenario. There are a few posts about doing that (I've seen this one pop up in google/bing results often).
这里是使用 PostSharp 执行此操作的示例。往帖子底部看。
Here is an example of doing this with PostSharp. Look towards the bottom of the post.
这是一个使用 IL Weaving 实现此目的的示例 < a href="https://github.com/Fody/Fody" rel="nofollow noreferrer">Fody/Mono.塞西尔。
基本上,这是一个注入 KnownTypeAttributes 在构建时使用 IL Weaving。
在构建管道期间,扩展会找到所有标有 KnowsDeriveTypes 属性(扩展的一部分)的基类,并且它将在派生的所有类(不是扩展的类)上添加 KnownTypeAttribute
必须直接来自上述基类之一(使用 KnowsDeriveTyepsAttribute)。
这是另一个帖子的镜像,在这里您可以找到该扩展的 Github 存储库。
This is an example of achieving this with IL Weaving using Fody/Mono.Cecil.
Basically, this is a Fody extension that injects KnownTypeAttributes during build time using IL Weaving.
During the build pipeline, the extension locates all base classes marked with the KnowsDeriveTypes attribute (Part of the extension) and it will add the KnownTypeAttribute over all classes that derive (not
necessarily directly) from one of the above base classes (with the KnowsDeriveTyepsAttribute).
This is another mirror for the post and here you can find the Github repo for the extension.