我刚刚进入MEF,我遇到了一个我无法解决的问题。我有一个Windows服务正在读取我的DLL(通过MEF),每个DLL是一个WCF服务主机。当我运行我的Windows服务并读入DLL时,一切运行正常,除了每当一个WCF DLL获得任何“活动”,然后他们重新实例化然后处理进来的数据。我需要它们在开始时实例化一次。这可能吗?
答案 0 :(得分:4)
您可以通过实施IServiceBehavior
和IInstanceProvider
来处理此问题,在IServiceBehavior
中注册OnStart
,并IInstanceProvider
管理对象的生命周期您。特别是,您可以使用控制容器的反转,在每个请求上提供服务类型的相同实例(即,不是单例的类似单例的行为)。
public partial class MyServiceHost : ServiceBase {
// details elided
protected override void OnStart(string[] args) {
this.Host = new ServiceHost(typeof(MySerivce));
this.Host.Description.Behaviors.Add(new MyServiceBehavior());
this.Host.Open();
}
}
public class MyServiceBehavior : IServiceBehavior {
public void AddBindingParameters(
ServiceDescription serviceDescription,
ServiceHostBase serviceHostBase,
Collection<ServiceEndpoint> endpoints,
BindingParameterCollection bindingParameters
) { }
public void ApplyDispatchBehavior(
ServiceDescription serviceDescription,
ServiceHostBase serviceHostBase) {
IIoCContainer container = new IocContainer();
foreach (var cdBase in serviceHostBase.ChannelDispatchers) {
ChannelDispatcher cd = cdBase as ChannelDispatcher;
if (cd != null) {
foreach (EndpointDispatcher ed in cd.Endpoints) {
ed.DispatchRuntime.InstanceProvider = new MyInstanceProvider(
container,
serviceDescription.ServiceType
);
}
}
}
}
public void Validate(
ServiceDescription serviceDescription,
ServiceHostBase serviceHostBase
) { }
}
public class MyInstanceProvider : IInstanceProvider {
readonly IIocContainer _container;
readonly Type _serviceType;
public InstanceProvider(IIoCContainer container, Type serviceType) {
_container = container;
_serviceType = serviceType;
}
public object GetInstance(InstanceContext instanceContext, Message message) {
return _container.Resolve(_serviceType);
}
public object GetInstance(InstanceContext instanceContext) {
return GetInstance(instanceContext, null);
}
public void ReleaseInstance(InstanceContext instanceContext, object instance) { }
}
答案 1 :(得分:4)
WCF服务默认为每次调用实例模式。这意味着为每个传入的方法调用实例化了一个新的WCF服务实例。听起来你想要的是 singleton 实例模式,但如果scability是一个问题,你真的想避免这种情况。
我解决这个问题的方法是使用 per calls 实例模式,但在我同步访问的场景后面有一个静态数据存储。这至少允许客户端连接,即使在建立连接后数据存储正在使用时它们必须暂时阻塞。
有关详细信息,请参阅System.ServiceModel.InstanceContextMode上的MSDN帮助。