简体   繁体   English

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

[英]Why Can You Expose Private Methods Publically in a WCF Service?

Why We can put the [ OperationContract ] Attribute on private methods in wcf services. 为什么我们可以将[ OperationContract ]属性放在wcf服务中的私有方法上。 From the day start of my programming i have been taught private methods are those which are not accessible outside the class. 从我编程的那天开始,我就被教导私人方法是那些在课外无法访问的方法。 Now in WCF service you can expose private method publicly. 现在,在WCF服务中,您可以公开公开私有方法。

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

Not sure why it's designed this way but if you check the source, line 336 says 不确定为什么它是这样设计的,但是如果你检查一下,第336行说

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

Note the NonPublic flag in particular. 特别注意NonPublic标志。 Then this gets used later on line 678 when WCF is using reflection to figure out which methods to expose: 然后,当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);
                }
                ...

I agree with you it's an odd decision but the WCF devs explicitly decided to make it this way by including the NonPublic flag. 我同意你这是一个奇怪的决定,但WCF开发人员明确决定通过包含NonPublic标志来做到这一点。

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

It's interesting to find it works. 找到它有用很有趣。 Surely, you use private access modifier to deny consumers of your class to access marked members. 当然,您使用私有访问修饰符来拒绝您的类的消费者访问标记的成员。 But WCF expose every method you mark with OperationContract attribute to public. 但是WCF会将您使用OperationContract属性标记的每个方法公开给public。 As Robert Levy found out, it is implemented that way. 正如Robert Levy所发现的那样,它就是以这种方式实现的。 Similarly, you can find some information in this presentation about WCF , especially slide no. 同样,您可以在此演示文稿中找到有关WCF的一些信息,尤其是幻灯片编号。 36 . 36

When you check the MSDN article about implementing WCF service , you may notice they use OperationContract attribute on private method. 当您检查有关实现WCF服务MSDN文章时 ,您可能会注意到它们在私有方法上使用OperationContract属性。 But it seems to be a typo because the class has to implement methods of its interface. 但它似乎是一个错字,因为该类必须实现其接口的方法。

Anyway, the safest way for you as a developer is to use ServiceContract and OperationContract attributes in service class interface, eg: 无论如何,作为开发人员,最安全的方法是在服务类接口中使用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 cents: 2美分:

SOAP, which is used by WCF, does not adhere to the OOPs concepts of C#. WCF使用的SOAP不遵循C#的OOP概念。 Another "anomaly" would be method overloading, which is a very useful and widely used C# feature. 另一个“异常”是方法重载,这是一个非常有用且广泛使用的C#特性。 While we can overload methods in the Service class, we cannot have two OperationContracts with the same name (even with different signature), which means that we cannot expose an overloaded method over SOAP. 虽然我们可以重载Service类中的方法,但是我们不能有两个具有相同名称的OperationContracts(即使具有不同的签名),这意味着我们不能通过SOAP公开重载方法。 Going by this, it would suggest that since scope specifiers are not a SOAP feature, WCF ignores it and goes by the OperationContract and DataMember attributes to decide the contracts. 通过这种方式,它会建议由于范围说明符不是SOAP功能,WCF会忽略它并通过OperationContract和DataMember属性来决定合同。

Following also gets exposed as a DataMember of DataContract : 以下内容也作为DataContract的DataMember公开:

[DataMember]
private int _personAge;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM