Wcf Service Known attribute type attribute

I want to add a service behavior (or something that suggests) that automatically inserts types from a dll into a service of known service types

Is it possible? as?

+3
source share
1 answer

Known type attributes are passed to the DataContractSerializer constructor. You can customize the way you create this serializer and provide known types of constructor for the serializer, reflecting your assemblies and find all types that are derived from the base class.

Here's a sample code (not tested):

[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;
    }
}
+7
source

Source: https://habr.com/ru/post/1712490/


All Articles