使用接口作为WCF服务的数据协定

时间:2014-05-20 17:14:39

标签: c# wcf interface datacontract

我正在寻找最好的方法。 我有一系列数据类型,我希望在一个方法下在WCF中返回。这就是为什么我有一个MarkerInterface,因此我不需要100个ServiceContracts / Methods来简单地转换数据。

不幸的是,所有DataContracts(例如currentbatch)都是唯一的,它们具有独特的属性集。我有一个Transformer的原因是它们都需要基于数据集的某种数据转换。

变压器接口如下:

public interface IDataTransformer
{
    IMarkerInterface Transform(DataSet inDataSet_);
}

然后我为每个datacontract都有一个变压器库(我将在下面解释)

public class CurrentBatch_Transformer : IDataTransformer
{
}

这是我将拥有的许多数据交换之一,它实现了IMarkerInterface。

[DataContract]
public class CurrentBatch : IMarkerInterface
{
    [DataMember]
    public string GroupName { get; set; }

    [DataMember]
    public bool FlagLocked { get; set; }
}

所以,因为我有一个IMarkerInterface;我可以将所有内容放在一个方法(GetDataUsingDataContract)中,并接收它们各自的变换器和一个DataSet。

    public IMarkerInterface GetDataUsingDataContract(IDataTransformer composite, DataSet inData_)
    {
        if (composite == null)
        {
            throw new ArgumentNullException("composite");
        }

        return composite.Transform(inData_);
    }

同样,我的问题是:

1)这是一个好习惯吗?如果不是这样的话。为什么,还有更好的方法吗?

2)在WCF序列化期间接口是否会被序列化? (我不希望它被序列化,但如果确实如此,我也不会介意。)

1 个答案:

答案 0 :(得分:2)

是的,这是可以接受的解决方案,但您必须让WCF知道您将使用哪种类型,因为它应该形成WSDL文档。您可以使用ServiceContract的ServiceKnownType属性,数据契约的KnownType或在配置中添加已知类型。

以下是示例:

  1. <强>的ServiceContract:

    [ServiceKnownType("GetKnownTypes", typeof(Helper))]
    [ServiceContract()]
    public interface IService
    {
        [OperationContract]
        IMarkerInterface GetMarker();
    }
    
    static class Helper 
    {
        static IEnumerable<Type> GetKnownTypes(ICustomAttributeProvider provider)
        {
            return new Type[] { typeof(CurrentBatch) };
        }
    }
    
  2. KnownType:

    [DataContract]
    [KnownType("GetKnownType")]  //there are few option of usage, you can apply for one concrete class: [KnownType(typeof(InheritedClass))]
    public class BaseClass
    {
    
        private static Type[] GetKnownType()
        {
            return return new Type[] { typeof(InheritedClass) };;
        }
    }
    
  3. 配置文件:

    <system.runtime.serialization>
      <dataContractSerializer>
        <declaredTypes>
          <add type="MyProject.IMarkerInterface, MyProjectAssembly">
            <knownType type="MyProject.CurrentBatch, MyProjectAssembly"/>
          </add>
        </declaredTypes>
      </dataContractSerializer>
    </system.runtime.serialization>