如何将流畅的MEF注入WCF
本文关键字:MEF 注入 WCF | 更新日期: 2023-09-27 18:20:15
我正在尝试使用fluent配置的MEF来使用自定义构造函数来增强我的WCF服务。
如何检查MEF容器是否提供"serviceType"。例如:
public class MyServiceHostFactory : ServiceHostFactory
{
private readonly CompositionContainer container;
public MyServiceHostFactory()
{
this.container = MyCompositionRoot.Instance.Container;
}
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
if (serviceType == ????)
{
return new MyServiceHost(container, serviceType, baseAddresses);
}
return base.CreateServiceHost(serviceType, baseAddresses);
}
}
然后我需要为我的行为添加一个实例提供者:
public MyServiceHost(CompositionContainer container, Type serviceType,
params Uri[] baseAddresses) : base(serviceType, baseAddresses)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
var contracts = this.ImplementedContracts.Values;
foreach (var c in contracts)
{
// Should I get the service obj here?
var serviceObj = container.GetExports(serviceType, null, null).First().Value;
var instanceProvider = new MyInstanceProvider(serviceObj); // ????
c.Behaviors.Add(instanceProvider);
}
}
但我不确定这个实例提供者应该是什么样子(它应该把serviceType
作为参数还是serviceObj
?
public partial class MyInstanceProvider : IInstanceProvider, IContractBehavior
因为在书中(.NET中的DI注入),示例使用了一个强耦合的实例提供程序,即MyServiceType1InstanceProvider
、MyServiceType2InstanceProvider
,但如果我有许多服务与fluent mef连接在一起,那就太乏味了。
实现这一点的一种方法是使用CompositionContainer
的GetExports方法。它返回一个IEnumerable<Lazy<Object, Object>>
。如果它至少包含一个元素,那么"serviceType"是可用的。
因此检查可以是:
if (container.GetExports(serviceType, null, null).Any())
{
return new MyServiceHost(container, serviceType, baseAddresses);
}
然后获得导出服务的方法可以是:
Object seviceObj = container.GetExports(serviceType, null, null).First().Value;
现在的问题是,值的类型是System.Object,您将不得不动态强制转换它或使用dynamic
关键字(并失去编译器的所有帮助)。
WCF服务默认为每调用实例模式。这意味着为每个传入的方法调用实例化一个WCF服务的新实例。听起来您想要的是一个单实例模式,但如果粗糙性是一个问题,您确实希望避免这种情况。
我解决这一问题的方法是使用每次调用实例模式,但在后台有一个静态数据存储,我可以同步访问它。这至少允许客户端进行连接,即使一旦建立连接,在数据存储使用时,它们必须暂时阻止。
有关更多详细信息,请参阅MSDN关于System.ServiceModel.InstanceContextMode的帮助。