繁体   English   中英

WCF服务内部方法重载

[英]WCF service internal method overloads

我有一个WCF服务,该服务根据传入的用户类型返回数据。此方法的定义是:

[OperationContract]
public Element GetElement(User user, int id)

我的问题是服务中有许多方法,每个方法都接受一个用户,并包含一个开关来返回有关用户类型的相关信息。

switch(user.GetType())
{
    case typeOf(UserA):
     break;
    case typeOf(UserB):
     break;
    case typeOf(UserC):
     break;
}

有什么方法可以实现下面的结构并使WCF自动定向到正确的方法? 可能是某种行为?

[OperationContract]
public Element GetElement(User user, int id)
{
     //DO NOTHING
}

public Element GetElement(UserA user, int id)
{
     //Process for typeof UserA
}

public Element GetElement(UserB user, int id)
{
     //Process for typeof UserB
}

public Element GetElement(UserC user, int id)
{
     //Process for typeof UserC
}

您可以通过实现IDispatchOperationSelector来执行类似的操作。 有一个很好的博客文章关于它在这里

不过,您可能会遇到方法名重载的问题-这种事情在网络上往往无法很好地工作。

我认为,您应该避免在公共数据契约上公开任何继承层次结构。 继承是一个非常面向对象的概念,不能很好地适应面向服务的上下文。

我建议以下内容:

取消定义您的服务合同的类库项目

namespace ClassLibrary1
{
    [ServiceContract]
    public interface IService1
    {

        [OperationContract]
        Element GetElement(User type);

    }

    [DataContract]
    public class Element
    {
        [DataMember]
        public string Name { get; internal set; }
    }


    [KnownType(typeof(UserA))]
    [KnownType(typeof(UserB))]
    [KnownType(typeof(UserC))]
    public class User
    {

        public Element GetElement()
        {
            return new Element() { Name = TypeName };
        }

        protected virtual string TypeName
        {
            get { return "base"; }
        }



    }

    public class UserA : User
    {
        protected override string TypeName
        {
            get { return "A"; }
        }
    }

    public class UserB : User
    {
        protected override string TypeName
        {
            get { return "B"; }
        }
    }

    public class UserC : User
    {
        protected override string TypeName
        {
            get { return "C"; }
        }
    }
}

创建您的服务项目,添加对您在步骤1中创建的类库的引用

使用ClassLibrary1;

namespace WcfServiceLibrary3
{
    public class Service1 : IService1
    {
        public Element GetElement(User type)
        {
            if (type == null) return null;

            return type.GetElement();
        }
    }
}

和配置文件

...
            <endpoint address="" binding="basicHttpBinding" contract="ClassLibrary1.IService1">
...

创建测试控制台应用程序并编写以下内容

using ClassLibrary1;
using ConsoleApplication10.ServiceReference1;

namespace ConsoleApplication10
{
    class Program
    {
        static void Main(string[] args)
        {
            var myService = new Service1Client();

            Console.WriteLine(myService.GetElement(new UserA()).Name);
            Console.WriteLine(myService.GetElement(new UserB()).Name);
            Console.WriteLine(myService.GetElement(new UserC()).Name);
        }
    }
}

输出将是

  • 一种
  • C

在查看了提供的答案并进行了一些挖掘之后,我遇到了IOperationInvoker。 这正是我所追求的。 我可以更改invoke方法,以使用反射根据输入查找正确的用户方法

http://msdn.microsoft.com/zh-CN/library/system.servicemodel.dispatcher.ioperationinvoker.invoke.aspx

暂无
暂无

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

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