简体   繁体   English

MEF + WCF服务主机?

[英]MEF + WCF Service Host?

I am just getting into MEF and I have come across a problem that I cannot resolve. 我刚刚进入MEF,我遇到了一个我无法解决的问题。 I have a windows service that is reading in my DLLs (via MEF) and each DLL is a WCF Service Host. 我有一个Windows服务正在读取我的DLL(通过MEF),每个DLL是一个WCF服务主机。 When I run my windows service and read in the DLLs everything runs fine, except that whenever one of the WCF DLLs get any "activity" then they reinstantiate and then process the data coming in. I need them to just instantiate once at the beginning. 当我运行我的Windows服务并读入DLL时,一切运行正常,除了每当一个WCF DLL获得任何“活动”,然后他们重新实例化然后处理进来的数据。我需要它们在开始时实例化一次。 Is this possible? 这可能吗?

You can handle this by implementing an IServiceBehavior and an IInstanceProvider , registering my implmentation of IServiceBehavior in OnStart , and having IInstanceProvider manage object lifetime for you. 你可以通过实现一个IServiceBehavior和一个IInstanceProvider来处理这个IInstanceProvider ,在OnStart注册我的IServiceBehavior ,并让IInstanceProvider为你管理对象的生命周期。 In particular, you can use an inversion of control container that serves up the same instance of your service type on each request (ie, singleton-like behavior without being a singleton). 特别是,您可以使用控制容器的反转,在每个请求上提供服务类型的相同实例(即,不是单例的类似单例的行为)。

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) { }       
}

WCF services default to a per call instance mode. WCF服务默认为每个调用实例模式。 This means that a new instance of your WCF service is instantiated for each incoming method invocation. 这意味着为每个传入的方法调用实例化了一个新的WCF服务实例。 It sounds like what you're wanting is a singleton instance mode, but you really want to avoid this if scability is an issue. 这听起来像你想要的是单例实例模式,但如果scability是一个问题,你真的想避免这种情况。

The way I've gotten around this is to use the per call instance mode, but have a static data store behind the scenes that I synchronize access to. 我得到的方法是使用每个调用实例模式,但在我同步访问的场景后面有一个静态数据存储。 This at least allows clients to connect, even if they have to block momentarily while the data store is in use once the connection is established. 这至少允许客户端连接,即使在建立连接时数据存储正在使用时它们必须暂时阻塞。

Refer to the MSDN help on System.ServiceModel.InstanceContextMode for more details. 有关更多详细信息,请参阅System.ServiceModel.InstanceContextMode上的MSDN帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM