如何使用Autofac使用WCF服务?

时间:2011-12-21 15:23:16

标签: wcf autofac

我知道使用Autofac,可以托管WCF服务。扭转方式怎么样?是否可以使用WCF使用Autofac服务?我的意思是客户端。如果是的话,怎么做?

3 个答案:

答案 0 :(得分:5)

看看http://code.google.com/p/autofac/wiki/WcfIntegration#Clients。 您只需通过注册ChannelFactory<IYourServiceContract>来注册绑定配置,然后注册通道创建。不要忘记调用UseWcfSafeRelease()。

答案 1 :(得分:2)

我建议您按照WCF integration wiki page的第一部分中的说明进行操作。

关于该实现的唯一注意事项是UseWcfSafeRelease在服务实例发布时调用ICommunicationObject.Close()。在我看来,这很糟糕,因为它会阻塞,直到Web调用完全处理所有缓冲区,并且在某些情况下它会阻止UI线程(在Silverlight中)。我最好打电话给ICommunicationObject.Abort(),因为如果我发布一个组件实例,就意味着我不再需要它的进程了。也就是说,我使用以下版本的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();
    }
}

虽然如果你更喜欢它,你肯定可以使用Autofac的内置客户端集成代码。

答案 2 :(得分:0)

@Pavel Gatilov 我通过反射器提取

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