Afshar
Afshar

Reputation: 11483

How to consume a WCF service using Autofac?

I know using Autofac, it is possible to host a WCF service. What about reversing the way? Is it possible to consume a WCF service using Autofac? I mean client side. If yes, how it can be done?

Upvotes: 4

Views: 3961

Answers (3)

user3697222
user3697222

Reputation: 1

@Pavel Gatilov I extract via reflector

private static void CloseChannel<T>(T channel)
{
    IClientChannel channel2 = (IClientChannel) channel;
    try
    {
        if (channel2.State == CommunicationState.Faulted)
        {
            channel2.Abort();
        }
        else
        {
            channel2.Close();
        }
    }
    catch (TimeoutException)
    {
        channel2.Abort();
    }
    catch (CommunicationException)
    {
        channel2.Abort();
    }
    catch (Exception)
    {
        channel2.Abort();
        throw;
    }
}

Upvotes: 0

rcaval
rcaval

Reputation: 762

Take a look at http://code.google.com/p/autofac/wiki/WcfIntegration#Clients . You just need to register the binding configuration by registering a ChannelFactory<IYourServiceContract>, and then register the channel creation. Don`t forget to call the UseWcfSafeRelease().

Upvotes: 5

Pavel Gatilov
Pavel Gatilov

Reputation: 7661

I recommend you follow instructions in the first section of the WCF integration wiki page.

The only note about that implementation is that UseWcfSafeRelease calls ICommunicationObject.Close() upon a service instance release. In my point of view, that's bad, because it blocks until a web call completely processes all buffers and in some cases it blocks UI thread (in Silverlight). I would better call ICommunicationObject.Abort() because if I release a component instance, it means I don't need its processes anymore. That said, I use the following version of the RegistrationExtensions class:

/// <summary>
/// Extend the registration syntax with WCF-specific helpers.
/// </summary>
public static class RegistrationExtensions
{
    /// <summary>
    /// Dispose the channel instance in such a way that exceptions 
    /// </summary>
    /// <typeparam name="TLimit">Registration limit type.</typeparam>
    /// <typeparam name="TActivatorData">Activator data type.</typeparam>
    /// <typeparam name="TRegistrationStyle">Registration style.</typeparam>
    /// <param name="registration">Registration to set release action for.</param>
    /// <returns>Registration builder allowing the registration to be configured.</returns>
    /// <remarks>This will eat exceptions generated in the closing of the channel.</remarks>
    public static IRegistrationBuilder<TLimit, TActivatorData, TRegistrationStyle>
        UseWcfSafeRelease<TLimit, TActivatorData, TRegistrationStyle>(
            this IRegistrationBuilder<TLimit, TActivatorData, TRegistrationStyle> registration)
    {
        if (registration == null) throw new ArgumentNullException("registration");
        return registration.OnRelease(CloseChannel);
    }

    static void CloseChannel<T>(T channel)
    {
        var disp = (IClientChannel) channel;
        disp.Abort();
    }
}

Although if you like it more, you can surely use the Autofac's built-in client-side integration code.

Upvotes: 2

Related Questions