wcf服务已知类型属性问题

时间:2009-07-13 18:42:58

标签: wcf

我想添加一个服务行为(或任何你建议的),它会自动将类型从dll插入服务已知类型的服务

有可能吗?怎么样?

1 个答案:

答案 0 :(得分:7)

已知类型属性将传递给DataContractSerializer构造函数。您可以customize the way this serializer is instantiated通过反映您的程序集并查找从基类派生的所有类型,将已知类型提供给序列化程序的constructor

这是一个示例代码(未经测试):

[ServiceContract]
public interface FooContract
{
    [OperationContract]
    [KnownTypesDataContractFormat(typeof(SomeBaseType))]
    void MyOperation(SomeBaseType arg);
}

public class KnownTypesDataContractFormatAttribute : Attribute, IOperationBehavior
{
    public Type BaseType { get; private set; }
    public KnownTypesDataContractFormatAttribute(Type baseType)
    {
        BaseType = baseType;
    }

    public void AddBindingParameters(OperationDescription description, BindingParameterCollection parameters)
    { }

    public void ApplyClientBehavior(OperationDescription description, System.ServiceModel.Dispatcher.ClientOperation proxy)
    {
        IOperationBehavior innerBehavior = new KnownTypesDataContractSerializerOperationBehavior(description, BaseType);
        innerBehavior.ApplyClientBehavior(description, proxy);
    }


    public void ApplyDispatchBehavior(OperationDescription description, System.ServiceModel.Dispatcher.DispatchOperation dispatch)
    {
        IOperationBehavior innerBehavior = new KnownTypesDataContractSerializerOperationBehavior(description, BaseType);
        innerBehavior.ApplyDispatchBehavior(description, dispatch);
    }

    public void Validate(OperationDescription description)
    { }
}

public class KnownTypesDataContractSerializerOperationBehavior : DataContractSerializerOperationBehavior
{
    public Type BaseType { get; private set; }
    public KnownTypesDataContractSerializerOperationBehavior(OperationDescription operationDescription, Type baseType) : base(operationDescription) 
    {
        BaseType = baseType;
    }

    public override XmlObjectSerializer CreateSerializer(Type type, string name, string ns, IList<Type> knownTypes)
    {
        return new DataContractSerializer(type, name, ns, knownTypes);
    }

    public override XmlObjectSerializer CreateSerializer(Type type, XmlDictionaryString name, XmlDictionaryString ns, IList<Type> knownTypes)
    {
        return new DataContractSerializer(type, name, ns, knownTypes);
    }

    private IEnumerable<Type> GetKnownTypes()
    {
        // Try to find all types that derive from BaseType in the 
        // executing assembly and add them to the knownTypes collection
        return 
            from type in Assembly.GetExecutingAssembly().GetTypes()
            where type != BaseType && BaseType.IsAssignableFrom(type)
            select type;
    }
}