如何将OperationContract应用于接口中的所有方法

时间:2013-09-10 14:25:19

标签: c# wcf attributes servicecontract operationcontract

我在我的wcf应用程序中创建了一个服务合同,它包含很多方法。

我觉得向所有人写一个OperationContract属性非常烦人。

有什么简单的方法可以说“我的ServiceContract界面中的每个方法都是OperationContract”吗?

谢谢

3 个答案:

答案 0 :(得分:2)

不,您需要在每个方法上执行此操作。它定义了一个服务,该服务是服务中服务合同的一部分。有些方法可能不适用于公开。

答案 1 :(得分:0)

是的,您可以使用AOP框架。例如。与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);
        }
    }
}

此属性用于标记不应为操作合同的方法:

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

现在您需要做的就是将AutoServiceContract属性应用于服务接口。这将为接口添加ServiceContract属性,并且所有公共方法都将使用OperationContact属性标记(具有NotOperationContract属性的属性除外):

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

答案 2 :(得分:0)

Spring.Net具有内置功能ServiceExporter,您只需要这样的配置:

<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>

有关详细信息,请查看documentation和此forum thread。您需要在app.config中使用与Spring对象相同的服务定义:MyService

下一步将使用DataContract属性装饰所有对象。有任何想法吗?不太好的是在服务合同上使用XmlSerializerFormat属性(也可以由Spring添加)。

相关问题