2011-06-07 48 views
12

我们有一个抽象类,它是我们通过WCF服务发送的许多不同请求的基础。这是一个丑陋的黑客攻击,每次我们添加一个新的请求时,我们都必须记住将[KnownType]属性添加到此基类中。抽象类的所有派生类型的KnownType?

有没有办法告诉DataContractSerializer将这个抽象类型的所有派生看作KnownType

回答

8

我在WCF服务中遇到了同样的问题,并做了下面的“不太可恶”的黑客工作来解决已知的类型限制。我只是为了展示替代选项而概述,由您决定是否更好。

  1. 在服务启动时,通过反射加载您想要公开的类型。例如。如果您的所有WCF公开的实体都来自共同的抽象基础(或更多),则从它们应该位于的程序集中加载所有类型。出于性能原因静态缓存这些类型。

  2. 创建返回上述缓存的类型,具有以下签名的静态方法: public static IEnumerable<Type> GetKnownTypes(ICustomAttributeProvider provider)

  3. 马克与下列属性的WCF接口 [ServiceKnownType("GetKnownTypes", typeof(StaticClassThatCachesTypes))]

这应该给你自动只要未来的开发人员将他们放在正确的位置,那么所有类型的或者将从您选择的基类派生的。 sembly。

+0

感谢您的支持。如果对于不同类型的契约有多个基类型(对每个基类必须有一个静态帮助器),它并没有真正扩大规模,但它确实需要人为因素。 :) – Joe 2011-06-07 15:31:27

+0

@Joe:不一定。如果您有多个基类,则无法阻止您在步骤1中一次加载所有派生类型。GetKnownTypes必须返回一个类型列表。实际的限制是你必须知道你所有的基类(并且在你添加一个新类时加载类型加载器),并且你必须知道它们的位置。 – 2011-06-07 22:55:59

+0

接受这是一个体面的解决方法。在语言/编译器级别有更聪明的东西还是很不错的...... – Joe 2011-06-21 11:53:34

2

除了Dan C.给出的另一种选择是切换到NetDataContractSerializer--它不需要已知的类型声明,因为它紧密耦合到确切的契约实现,因此您需要共享程序集包含客户端和服务器之间的类型 - 在这种情况下,您肯定会失去互操作性。有几个关于这样做的帖子(我经常在google/bing结果中看到this one)。

+0

是的,我希望避免这种依赖。 (还是)感谢你的建议。 – Joe 2011-06-07 15:26:12

-1

Here是使用PostSharp完成此操作的一个示例。看看帖子的底部。

-1

This是使用IL编织使用Fody/Mono.Cecil来实现此目的的一个示例。

基本上,这是一个Fody扩展名,它在使用IL Weaving编译时注入KnownTypeAttributes

在生成管道,扩展位于标有KnowsDeriveTypes所有基类属性(扩展的部分),将它从上述的一个以上的是(直接地不 一定)导出所有类添加KnownTypeAttribute基类(使用KnowsDeriveTyepsAttribute)。

This是另一个帖子的镜像,here你可以找到扩展的Github回购。

+0

不要发布仅链接的答案;如果链接消失,那么这是一个无用的帖子。 – Joe 2018-02-26 13:46:35

+0

@Joe我已经添加了一个简单的解释,更多的镜像链接。我不确定在一个Stackoverflow答案中解释整个博客帖子是个好主意。 – m1o2 2018-02-27 10:16:50

相关问题