MEF + WCF 服务主机?

发布于 2024-08-14 07:38:42 字数 185 浏览 3 评论 0原文

我刚刚进入 MEF,遇到了一个无法解决的问题。我有一个 Windows 服务正在读取我的 DLL(通过 MEF),每个 DLL 都是一个 WCF 服务主机。当我运行 Windows 服务并读取 DLL 时,一切都运行良好,除了每当其中一个 WCF DLL 获得任何“活动”时,它们就会重新实例化,然后处理传入的数据。我需要它们在开始时实例化一次。这可能吗?

I am just getting into MEF and I have come across a problem that I cannot resolve. I have a windows service that is reading in my DLLs (via MEF) and each DLL is a WCF Service Host. 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. Is this possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

手心的海 2024-08-21 07:38:42

WCF 服务默认为每次调用实例模式。这意味着将为每个传入方法调用实例化 WCF 服务的新实例。听起来您想要的是单例实例模式,但如果可扩展性是一个问题,您确实希望避免这种情况。

我解决这个问题的方法是使用每次调用实例模式,但在后台有一个静态数据存储来同步访问。这至少允许客户端进行连接,即使在建立连接后客户端在使用数据存储时必须暂时阻塞。

请参阅有关 System.ServiceModel.InstanceContextMode 了解更多详情。

WCF services default to a per call instance mode. This means that a new instance of your WCF service is instantiated for each incoming method invocation. It sounds like what you're wanting is a singleton instance mode, but you really want to avoid this if scability is an issue.

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.

困倦 2024-08-21 07:38:42

您可以通过实现 IServiceBehaviorIInstanceProvider 来处理此问题,在 OnStart 中注册我的 IServiceBehavior 实现,并让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) { }       
}

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. In particular, you can use an inversion of control container that serves up the same instance of your service type on each request (i.e., 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) { }       
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文