Mike Norgate
Mike Norgate

Reputation: 2431

WCF service internal method overloads

I have a WCF service which returns data based on the user type that is passed in. The definition for this method is:

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

The problem I have is that there a number of methods in the service and each one takes in a user and contains a switch to return the relevant information for the type of user. i.e

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

Is there any way to be able to implement the below structure and have WCF automatically direct to the correct method? Possibly by some sort of behaviour?

[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
}

Upvotes: 0

Views: 143

Answers (3)

Mike Norgate
Mike Norgate

Reputation: 2431

After looking at the answers provided and do some digging I came across IOperationInvoker. This did exactly what I was after. I could change the invoke method to use reflection to lookup the correct user method based on the inputs

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

Upvotes: 0

Yaugen Vlasau
Yaugen Vlasau

Reputation: 2218

I would suggest the following:

Defile a class library project where define your service contracts

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

create your service project, add reference to the class library you created on step 1

using ClassLibrary1;

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

            return type.GetElement();
        }
    }
}

and the config file

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

create test console application and write the following

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

the output will be

  • A
  • B
  • C

Upvotes: 0

Lawrence
Lawrence

Reputation: 3297

You may be able to do something similar by implementing IDispatchOperationSelector. There is a nice blog post about it here.

You may run in to problems with the overloaded method names though - that sort of thing doesn't tend to work nicely over the wire.

In my opinion, you should avoid exposing any inheritance hierarchy over the public data contract. Inheritance is a very OO concept, and does not fit in to a service orientated context nicely.

Upvotes: 1

Related Questions