WCF服务内部方法重载

时间:2013-10-15 13:19:10

标签: c# wcf

我有一个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
}

3 个答案:

答案 0 :(得分:1)

您可以通过实施IDispatchOperationSelector来做类似的事情。有一篇关于它的好文章here

你可能会遇到重载方法名称的问题 - 这种事情往往不能很好地通过网络。

在我看来,您应该避免在公共数据协定上公开任何继承层次结构。继承是一个非常OO的概念,并不能很好地适应面向服务的上下文。

答案 1 :(得分:0)

我建议如下:

定义一个定义服务合同的类库项目

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);
        }
    }
}

输出将是

  • A
  • C

答案 2 :(得分:0)

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

查找正确的用户方法

http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.ioperationinvoker.invoke.aspx