Search code examples
c#wcfattributesservicecontractoperationcontract

how to apply OperationContract to all methods in interface


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


Solution

  • 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);
        // ...
    }