我正在尝试使用流畅配置的MEF来使用自定义构造函数来提升我的WCF服务。
如何检查MEF容器是否提供" serviceType"。 E.g:
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
- 但如果我有很多服务与流畅相关,那将会很乏味MEF。
答案 0 :(得分:1)
执行此操作的一种方法是使用CompositionContainer
的{{3}}方法。它返回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类型,你可以将它强制转换为GetExports或使用dynamic
关键字(并且松散了编译器的所有帮助)。
答案 1 :(得分:0)
WCF服务默认为每个调用实例模式。这意味着为每个传入的方法调用实例化了一个新的WCF服务实例。听起来你想要的是单例实例模式,但如果scability是一个问题,你真的想避免这种情况。
我解决这个问题的方法是使用每个调用实例模式,但在我同步访问的场景后面有一个静态数据存储。这至少允许客户端连接,即使在建立连接后数据存储正在使用时它们必须暂时阻塞。
有关详细信息,请参阅System.ServiceModel.InstanceContextMode上的MSDN帮助。