为什么可以在 WCF 服务中公开私有方法

本文关键字:有方法 服务 WCF 为什么 | 更新日期: 2023-09-27 18:34:47

为什么我们可以将 [ OperationContract ] 属性放在 wcf 服务中的私有方法上。从我编程的那一天起,我就被教导私人方法是那些在课堂外无法访问的方法。现在,在 WCF 服务中,您可以公开私有方法。

    [ServiceContract]
    public class MyServices
    {
        [OperationContract]
        private int add(int a,int b)
        {
            return a + b;
        }
    }

为什么可以在 WCF 服务中公开私有方法

不知道为什么它是这样设计的,但如果你检查源代码,第 336 行说

internal const BindingFlags ServiceModelBindingFlags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance;

请特别注意非公共标志。 然后,当 WCF 使用反射来确定要公开的方法时,将在第 678 行使用此方法:

   static List<MethodInfo> GetMethodsInternal(Type interfaceType)
   {
            List<MethodInfo> methods = new List<MethodInfo>();
            foreach (MethodInfo mi in interfaceType.GetMethods(ServiceModelBindingFlags))
            {
                if (GetSingleAttribute<OperationContractAttribute>(mi) != null)
                {
                    methods.Add(mi);
                }
                ...

我同意你的看法,这是一个奇怪的决定,但 WCF 开发人员明确决定通过包含非公共标志来做到这一点。

http://referencesource.microsoft.com/#System.ServiceModel/System/ServiceModel/Description/ServiceReflector.cs,c1358e6f97071bfa

发现它有效很有趣。当然,您可以使用私有访问修饰符来拒绝类的使用者访问标记的成员。但是,WCF 将您用OperationContract属性标记的每个方法都公开给公众。正如罗伯特·利维(Robert Levy(所发现的那样,它是以这种方式实现的。同样,您可以在本演示文稿中找到有关 WCF 的一些信息,尤其是第 36 张幻灯片。

当您查看有关实现 WCF 服务的 MSDN 文章时,您可能会注意到它们在私有方法上使用 OperationContract 属性。但这似乎是一个错别字,因为该类必须实现其接口的方法。

无论如何,作为开发人员,最安全的方法是在服务类接口中使用ServiceContractOperationContract属性,例如:

[ServiceContract]
public interface IMyService 
{
    [OperationContract]
    string GetData();
}
public class MyService : IMyService 
{
    public string GetData() { ... }
    private string ComputeData() { ... } // this one is not visible to clients
}

2 美分:

WCF 使用的 SOAP 不遵循 C# 的 OOPs 概念。另一个"异常"是方法重载,这是一个非常有用且广泛使用的 C# 功能。虽然我们可以在 Service 类中重载方法,但我们不能有两个同名的 OperationContract(即使签名不同(,这意味着我们不能通过 SOAP 公开重载方法。通过这一点,它表明由于范围说明符不是 SOAP 功能,WCF 会忽略它,而是通过 OperationContract 和 DataMember 属性来决定协定。

以下也会被公开为数据合约的数据成员:

[DataMember]
private int _personAge;