数据协定已知类型和一组相互继承的接口

Posted

技术标签:

【中文标题】数据协定已知类型和一组相互继承的接口【英文标题】:Data Contract Known Types and a set of interfaces inheriting each other 【发布时间】:2012-07-01 15:03:55 【问题描述】:

我开发(重写到 WCF)一个文件解析 web 服务接受 string[] 并返回 ISection[] 但实际上这是一组嵌套接口:

namespace Project.Contracts // Project.Contracts.dll

    public interface ISection  

    public interface ISummarySection : ISection  

    public interface IDataSection : ISection  

和类:

namespace Project.Format.A // Project.Format.A.dll

    [DataContract]
    public class SummarySectionFormatA : ISummarySection  

    [DataContract]
    public class DataSectionFormatA : IDataSection  

服务接口及其实现:

[ServiceContract]
public interface IService // Project.Contracts.dll

    ISection[] Parse(string format, string[] data);
 

[ServiceKnownType(typeof(SummarySectionFormatA))] // tried this also
[ServiceKnownType(typeof(DataSectionFormatA))]
public class Service : IService // Project.Service.dll

    public ISection[] Parse(string format, string[] data)
    
        return Factory.Create(format).Parse(data);
    

我尝试在服务器和客户端上都配置declaredTypes

<system.runtime.serialization>
  <dataContractSerializer>
    <declaredTypes>
      <add type="Project.Contracts.ISumarySection, Project.Contracts">
        <knownType type="Project.Format.A.SummarySectionFormatA, Project.Format.A" />
      </add>
      <add type="Project.Contracts.IDataSection, Project.Contracts">
        <knownType type="Project.Format.A.DataSectionFormatA, Project.Format.A" />
      </add>
    </declaredTypes>
  </dataContractSerializer>
</system.runtime.serialization>

但还是报同样的错误:

“不应使用数据合同名称“DataSection:http://schemas.example.com/Parse”键入“DataSectionFormatA”。

底层连接已关闭:连接意外关闭。

我无法使用 KnownTypeAttribute 装饰接口,因为 Contracts 项目不引用 Format 项目,并且引用会破坏设计。这就是我想使用config的原因。

【问题讨论】:

能否请您发布您的服务运营合同 【参考方案1】:

看看下面的代码

[ServiceContract]
[ServiceKnownType(typeof(SummarySectionFormatA))]
[ServiceKnownType(typeof(DataSectionFormatA))]
public interface IService 

public class Service : IService 

【讨论】:

好的,我知道了。所以你建议装饰接口(服务合同)但不装饰实现。但正如我在问题底部提到的那样,我不想这样做,因为接口被放置在 Contracts.dll 中,它不引用其他项目内 dll,并且它不能防止循环引用。我想使用一个配置。【参考方案2】:

我相信你应该稍微改变你的实现......看看这个question,看看它是否有帮助。

【讨论】:

对。我的主要问题是为什么配置不起作用。似乎是因为没有引用项目(我想避免)并且 Type.GetType() 返回 null。确实需要改变实现。 正确!问题是服务依赖于未知的东西......另外我想质疑数据合同接口的使用,你为什么打算抽象它。建议将其具体化或从这个角度考虑。 这是最初的设计,它作为 Web 应用程序的一部分运行良好。现在,我将解析逻辑从应用程序分离到一个专用的 Web (WCF) 服务中,因此首先尝试在不进行重大设计更改的情况下做到这一点。 分享一下你最终完成的设计。 配置和属性方式都适用于我,条件是向服务器和客户端引用所有已知类型的项目。【参考方案3】:

试图让这个工作:

[KnownType("GetKnownType")]
public class Section

    static Type[] GetKnownType()
    
        return new[]
        
            Type.GetType("Project.Format.A.DataSectionFormatA, Project.Format.A")
        ;
    

但似乎服务器和客户端都必须引用 Project.Format.A.dll 才能使其工作(方法不返回null)

【讨论】:

以上是关于数据协定已知类型和一组相互继承的接口的主要内容,如果未能解决你的问题,请参考以下文章

接口继承自System.Object吗?

第四篇:协调和协定之故障检测和互斥算法

JAVA 第六章知识回顾与总结

201671010138 2016-2017-2《java程序设计》学习心得

第三章:继承/抽象类/接口

Go-接口类型详解(定义实现接口继承比较等)