how to apply OperationContract to all methods in i

2019-07-20 20:29发布

问题:

Im creating a service contract in my wcf application and it contains a lot of methods.

I find it very annoying to write an OperationContract attribute to all of them.

Is there any simple way how to say "every method in my ServiceContract interface is an OperationContract" ?

thank you

回答1:

Yes, you can use AOP framework for that. E.g. with PostSharp:

[Serializable]
public sealed class AutoServiceContractAttribute : TypeLevelAspect, IAspectProvider
{
    // This method is called at build time and should just provide other aspects.
    public IEnumerable<AspectInstance> ProvideAspects(object targetElement)
    {
        Type targetType = (Type)targetElement;

        var introduceServiceContractAspect =
            new CustomAttributeIntroductionAspect( 
                new ObjectConstruction(typeof(ServiceContractAttribute)
                                          .GetConstructor(Type.EmptyTypes)));
        var introduceOperationContractAspect =
            new CustomAttributeIntroductionAspect( 
                new ObjectConstruction(typeof(OperationContractAttribute)
                                         .GetConstructor(Type.EmptyTypes)));

        // Add the ServiceContract attribute to the type.
        yield return new AspectInstance(targetType, introduceServiceContractAspect);

        // Add a OperationContract attribute to every relevant method.
        var flags = BindingFlags.Public | BindingFlags.Instance;
        foreach (MethodInfo method in targetType.GetMethods(flags))
        {
            if (!method.IsDefined(typeof(NotOperationContractAttribute), false))
                yield return new AspectInstance(method, introduceOperationContractAspect);
        }
    }
}

This attribute used to mark methods which should not be operation contracts:

[AttributeUsage(AttributeTargets.Method)]
public sealed class NotOperationContractAttribute : Attribute
{
}

Now all you need to do is apply AutoServiceContract attribute to service interface. That will add ServiceContract attribute to interface, and all public methods will be marked with OperationContact attribute (except those which have NotOperationContract attribute):

[AutoServiceContract]
public interface IService1
{
    public void Method1();
    [NotOperationContact]
    public string Method2);
    public int Method3(int a);
    // ...
}


回答2:

No, you need to do it on each and every method. it defines an operation that is part of a service contract in a Service. There is a possibility that some of the methods are not intended for Exposing.



回答3:

Spring.Net has built-in feature ServiceExporter and all you need is such config:

<object id="MyServiceExporter" type="Spring.ServiceModel.ServiceExporter, Spring.Services">
  <property name="TargetName" value="MyService" />
  <property name="TypeAttributes">
  <list>
    <object type="System.ServiceModel.ServiceBehaviorAttribute, System.ServiceModel">
      <property name="ConfigurationName" value="MyService"/>
    </object>
  </list>
  </property>
</object>
<object id="MyService" singleton="false" type="Eluzzion.TOrder.Service.OrderExportService, Eluzzion.TOrder.Service" />
<object id="MyServiceHost" type="Spring.ServiceModel.Activation.ServiceHostFactoryObject, Spring.Services" lazy-init="false" >
  <property name="TargetName" value="MyServiceExporter" />
</object>

For more details check documentation and this forum thread. You need to have service definition in app.config called same as the Spring object: MyService

Next step will be to decorate all objects with DataContract attribute. Any ideas? Not very good one is to use XmlSerializerFormat attribute on service contracts (can be added by Spring too).