简体   繁体   中英

WCF Client - Best Practise

I just wanted to hear your Opinion about a WCF Client implementation.

I have an Server that provides several services like SecurityManager. This service is defined in the Interface ISecurityManager and implemented in the Class SecurityManager.

So far everything is fine. On the Client side I want to implement the services calls via a seperated Class. My question is whether I do this also in an SecurityManager Class which implements the same ISecurityManager Interface?

What is here the best practise?

I would suggest to use a generic Wrapper make WCF calls. So everytime you need to make a WCF call you can do it like this:

var invoker = new ServiceInvoker();
        var result = invoker.InvokeService<ISecurityManager, MyObjectReturnType>(
            proxy => proxy.DoSomething(myParameters));
        return result;

I use ServiceInvoker to create the channel and manage any exceptions that would occur inside. It creates a channel with the ISecurityManager contract, with return type of MyObjectReturnType and with the action DoSomething (method from ISecurityManager contract). You can use this solution with all your interfaces, without any extra class implementation!

InvokeService would be something like this:

public TResult InvokeService<TServiceContract, TResult>(Func<TServiceContract, TResult> invokeHandler) where TServiceContract : class
    {
        ICommunicationObject communicationObject;
        var arg = CreateCommunicationObject<TServiceContract>(out communicationObject);
        var result = default(TResult);
        try
        {
            result = invokeHandler(arg);
        }
        catch (Exception ex)
        {
            Logger.Log(ex);
            throw;
        }

        finally
        {
            try
            {
                if (communicationObject.State != CommunicationState.Faulted)
                    communicationObject.Close();
            }
            catch
            {
                communicationObject.Abort();
            }
        }
        return result;
    }

private TServiceContract CreateCommunicationObject<TServiceContract>(out ICommunicationObject communicationObject)
        where TServiceContract : class
    {
        //Create the Channel
        // ICommunicationObject is an out parameter for disposing purposes 
        return channel;
    }

Visual Studio Generator

You can ask Visual Studio to build a client for you, right-clicking your client project and adding a Service Reference . There's a dialog where you can either type your service url or discover it from within the solution.

Creating a Client

You can build the client class inheriting from ClientBase<ISecurityManager>, ISecurityManager . Being an operation example on this client class:

public void ExampleMethod(int id)
{
   Channel.ExampleMethod(id);
}

Like a real man does

Or without any client class, just calling it:

ServiceInvokerinvoker invoker = new ServiceInvoker(); 
var result = invoker.InvokeService<ISecurityManager, ReturnType>(     proxy => proxy.ExampleMethod(1) ); 

Last two options assuming you already have configured the ISecurityManager client:

<client>     
<endpoint name="ServiceName" 
address="http://ServiceName.test/Service" 
binding="basicHttpBinding"   
contract="ISecurityManager" /> 
</client> 

To implement the service calls "via a separate class" you can just generate a service reference using svcutil.exe or visual studio from a running instance of your service.

This will generate a set of types off your service contract which will be completely "separate" from the assemblies containing your service contract and implementation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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