我有一个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
}
答案 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);
}
}
}
输出将是
答案 2 :(得分:0)
在查看提供的答案并进行一些挖掘之后,我遇到了IOperationInvoker。这完全是我追求的。我可以更改invoke方法以使用反射来根据输入
查找正确的用户方法http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.ioperationinvoker.invoke.aspx