我们有一个抽象类,它是我们通过WCF服务发送的许多不同请求的基础。这是一个丑陋的黑客攻击,每次我们添加一个新的请求时,我们都必须记住将[KnownType]
属性添加到此基类中。抽象类的所有派生类型的KnownType?
有没有办法告诉DataContractSerializer
将这个抽象类型的所有派生看作KnownType
?
我们有一个抽象类,它是我们通过WCF服务发送的许多不同请求的基础。这是一个丑陋的黑客攻击,每次我们添加一个新的请求时,我们都必须记住将[KnownType]
属性添加到此基类中。抽象类的所有派生类型的KnownType?
有没有办法告诉DataContractSerializer
将这个抽象类型的所有派生看作KnownType
?
我在WCF服务中遇到了同样的问题,并做了下面的“不太可恶”的黑客工作来解决已知的类型限制。我只是为了展示替代选项而概述,由您决定是否更好。
在服务启动时,通过反射加载您想要公开的类型。例如。如果您的所有WCF公开的实体都来自共同的抽象基础(或更多),则从它们应该位于的程序集中加载所有类型。出于性能原因静态缓存这些类型。
创建返回上述缓存的类型,具有以下签名的静态方法: public static IEnumerable<Type> GetKnownTypes(ICustomAttributeProvider provider)
马克与下列属性的WCF接口 [ServiceKnownType("GetKnownTypes", typeof(StaticClassThatCachesTypes))]
这应该给你自动只要未来的开发人员将他们放在正确的位置,那么所有类型的或者将从您选择的基类派生的。 sembly。
除了Dan C.给出的另一种选择是切换到NetDataContractSerializer--它不需要已知的类型声明,因为它紧密耦合到确切的契约实现,因此您需要共享程序集包含客户端和服务器之间的类型 - 在这种情况下,您肯定会失去互操作性。有几个关于这样做的帖子(我经常在google/bing结果中看到this one)。
是的,我希望避免这种依赖。 (还是)感谢你的建议。 – Joe 2011-06-07 15:26:12
Here是使用PostSharp完成此操作的一个示例。看看帖子的底部。
This是使用IL编织使用Fody/Mono.Cecil来实现此目的的一个示例。
基本上,这是一个Fody扩展名,它在使用IL Weaving编译时注入KnownTypeAttributes。
在生成管道,扩展位于标有KnowsDeriveTypes所有基类属性(扩展的部分),将它从上述的一个以上的是(直接地不 一定)导出所有类添加KnownTypeAttribute基类(使用KnowsDeriveTyepsAttribute)。
感谢您的支持。如果对于不同类型的契约有多个基类型(对每个基类必须有一个静态帮助器),它并没有真正扩大规模,但它确实需要人为因素。 :) – Joe 2011-06-07 15:31:27
@Joe:不一定。如果您有多个基类,则无法阻止您在步骤1中一次加载所有派生类型。GetKnownTypes必须返回一个类型列表。实际的限制是你必须知道你所有的基类(并且在你添加一个新类时加载类型加载器),并且你必须知道它们的位置。 – 2011-06-07 22:55:59
接受这是一个体面的解决方法。在语言/编译器级别有更聪明的东西还是很不错的...... – Joe 2011-06-21 11:53:34