Zulfiqar's weblog

Architecture, security & random .Net

Adding Dynamic methods to a WCF Service

Posted by zamd on February 5, 2010


Someone asked me if it’s possible to add a Ping method to every service contract without repeatedly defining it in each service contract?  The answer is yes & and it’s fairly simply too.

Here I have a LoginService, which require that implicit Ping method (DateTime Ping(){})like all other service.

 

[ServiceContract]

class LoginService

{

    [OperationContract]

    public bool Login(string userName, string password)

    {

        return true;

    }

}

This is how you would configure your host for these implicit methods.

class Program

{

    static void Main(string[] args)

    {

        var sh = new ServiceHost(typeof(LoginService), new Uri(http://localhost:9001”));

 

        GeneratePingMethod(sh);

        sh.Open();

 

        Console.ReadLine();

        sh.Close();

    }

}

 

Please note “GeneratePingMethod” adds the Ping method to every endpoint.  I’m simply creating the operation using the WCF description API and adding it into the description tree. PingImplementationBehavior plugs in a custom OperationInvoker which calls the actual Ping implementation.

 

private static void GeneratePingMethod(ServiceHost sh)

{

    foreach (var endpoint in sh.Description.Endpoints)

    {

        var cd = endpoint.Contract;

        var od = new OperationDescription(“Ping”, cd);

        var inputMsg = new MessageDescription(cd.Namespace + cd.Name + “/Ping”, MessageDirection.Input);

        var outputMsg = new MessageDescription(cd.Namespace + cd.Name + “/PingResponse”, MessageDirection.Output);

        var retVal = new MessagePartDescription(“PingResult”, cd.Namespace); ;

        retVal.Type = typeof(DateTime);

 

        outputMsg.Body.ReturnValue = retVal;

 

 

        od.Messages.Add(inputMsg);

        od.Messages.Add(outputMsg);

 

        od.Behaviors.Add(new DataContractSerializerOperationBehavior(od));

        od.Behaviors.Add(new PingImplementationBehavior());

 

        cd.Operations.Add(od);

    }

}

 

class PingImplementationBehavior : IOperationBehavior

{

    public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters)

    { }

 

    public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)

    { }

 

    public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)

    {

        dispatchOperation.Invoker = new PingInvoker();

    }

 

    public void Validate(OperationDescription operationDescription)

    { }

}

Again a fairly simple invoker which is tightly coupled to the signature of Ping method.

class PingInvoker : IOperationInvoker

{

    public object[] AllocateInputs()

    {

        return new object[0];

    }

 

    public object Invoke(object instance, object[] inputs, out object[] outputs)

    {

        outputs = new object[0];

        return Ping();

    }

 

    public IAsyncResult InvokeBegin(object instance, object[] inputs, AsyncCallback callback, object state)

    {

        throw new NotImplementedException();

    }

 

    public object InvokeEnd(object instance, out object[] outputs, IAsyncResult result)

    {

        throw new NotImplementedException();

    }

 

    public bool IsSynchronous

    {

        get { return true; }

    }

 

    public static DateTime Ping()

    {

        return DateTime.Now;

    }

}

Advertisements

8 Responses to “Adding Dynamic methods to a WCF Service”

  1. […] Source line :- http://zamd.net/2010/02/05/adding-dynamic-methods-to-a-wcf-service/ […]

  2. […] Adding Dynamic methods to a WCF Service February 2010 1 comment 4 […]

  3. […] Adding Dynamic methods to a WCF Service February 2010 1 comment 4 […]

  4. Giuseppe said

    Hi,
    i read your post about and it is very interesting.
    Following the example i can add a new method, but how i can call it ?

    It is not part of the wcf exposed interface. What can i do to call the new method ?

    Thanks in advance,

  5. chispa said

    Hi,

    I have also been able to implement adding a dynamic operation, but so far have no luck in figuring out how to call the operation i added dynamically. ChannelFactory factory = new ChannelFactory to try and achive this but with no luck.

    Please offer some guidance if any of you guys was able to figure this out.

  6. jarlef said

    Would be simpler just to create a base class e.g BaseService with a ping method and inherit every service from that base class. But i guess your post was more angled at showing the more dynamic side of wcf 😉

  7. Girish said

    hi, is there any way by which we can verify whether the method is actually added? and how can we call this newly added method?

    • zamd said

      Hi, the newly added method should be visible in the WSDL and the generated client proxy, if you use Add Service Reference wizard or the svcutil.exe.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: