我知道使用Autofac
,可以托管WCF
服务。扭转方式怎么样?是否可以使用WCF
使用Autofac
服务?我的意思是客户端。如果是的话,怎么做?
答案 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;
}
}