【问题标题】:KnownType for all derived types of an abstract class?抽象类的所有派生类型的 KnownType?
【发布时间】:2011-06-07 14:03:57
【问题描述】:

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

有没有办法告诉DataContractSerializer 将此抽象类型的所有派生视为KnownType?

【问题讨论】:

    标签: .net wcf abstract-class known-types


    【解决方案1】:

    我在 WCF 服务中遇到了同样的问题,并做了以下“不那么令人发指”的黑客攻击来解决已知的类型限制。我概述只是为了显示替代选项,由您决定是否更好。

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

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

    3. 使用以下属性标记 WCF 接口 [ServiceKnownType("GetKnownTypes", typeof(StaticClassThatCachesTypes))]

    这应该让您自动公开所有从您选择的基类派生或将派生的类型,只要未来的开发人员将它们放在正确的组装。

    【讨论】:

    • 谢谢。如果不同类型的合约有多种基础类型(每个基础都必须有一个静态助手),它并没有真正扩展,但它确实消除了人为因素。 :)
    • @Joe:不一定。如果您有多个基类,则没有什么可以阻止您在步骤 1 中一次性加载它们的所有派生类型。GetKnownTypes 必须返回一个类型列表。实际的限制是您必须知道所有基类(并在添加新基类时调整类型加载器),并且您必须知道它们的位置。
    • 接受这是一个不错的解决方法。在语言/编译器级别拥有更智能的东西仍然会很好......
    【解决方案2】:

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

    【讨论】:

    • 是的,我希望避免这种依赖。不过感谢您的建议。
    【解决方案3】:

    Here 是使用 PostSharp 执行此操作的示例。往帖子底部看。

    【讨论】:

      【解决方案4】:

      This 是使用Fody/Mono.Cecil 通过 IL Weaving 实现此目的的一个示例。

      基本上,这是一个 Fody 扩展,在构建期间使用 IL Weaving 注入 KnownTypeAttributes。

      在构建管道期间,扩展定位所有标有 KnowsDeriveTypes 属性的基类(扩展的一部分),并将 KnownTypeAttribute 添加到所有派生类(不是 必须直接)来自上述基类之一(使用 KnowsDeriveTyepsAttribute)。

      This 是该帖子的另一个镜像,here 你可以找到该扩展的 Github 存储库。

      【讨论】:

      • 不要发布仅链接的答案;如果链接消失,那么这是一个无用的帖子。
      • @Joe 我已经为链接添加了一个带有更多镜像的简短说明。我不确定在一个 Stackoverflow 答案中解释整篇博文是否是个好主意。
      猜你喜欢
      • 2011-01-11
      • 2021-08-04
      • 1970-01-01
      • 1970-01-01
      • 2017-04-28
      • 1970-01-01
      • 2023-04-11
      • 2011-02-01
      • 2021-05-17
      相关资源
      最近更新 更多