首页 > 解决方案 > 如何在本地计算机上安装的多个 WCF 服务之间共享属性?

问题描述

我有一个托管多个 WCF 服务的 Windows 服务。所有这些都在本地机器上运行(使用 NamePipe)。
有没有一种简单的方法让这些 WCF 服务共享一个属性?(我宁愿不让他们共享文件)。
我需要这个,因为在每个 WCF 服务中实例化的每个会话都将占用给定的硬件,而其他 WCF 服务需要知道什么仍然可用,以便能够实例化另一个会话。
每个 WCF 服务实现不同的协议,这就是我没有合并很多的原因。每个主机将有一个代理。

标签: c#wcf

解决方案


我不知道让服务实例共享属性的超级简单方法,但是您可以创建一个从 ServiceHost 派生的自定义主机并让它实现特定的接口,比如:

public interface ISharedStateContainer
{
  SharedState State { get; set; }
}

这个接口必须知道你的服务。然后,在您的 Windows 服务项目中,您可以创建一个自定义服务主机:

public class CustomServiceHost: ServiceHost, ISharedStateContainer
{
   SharedState state;
   public SharedState State{ get{ return state; } set{ state=value; } }       
}

...然后当 windows 服务创建 wcf 服务主机实例时,它可以注入共享状态:

var sharedState = new SharedState();

myServiceHost = new CustomServiceHost( typeof( MyService ) );
((ISharedStateContainer) myServiceHost).State = sharedState;

myOtherHost = new CustomServiceHost( typeof( OtherService ) );
((ISharedStateContainer) myOtherHost).State = sharedState;

myServiceHost.Open();
myOtherHost.Open();

...然后,在服务的运行实例中,您可以像这样进入共享状态:

var sharedState = ((ISharedStateContainer)OperationContext.Current.Host).State

在我拥有的地方SharedState,您可以将其设为任何您想要的类型……但将其设为本身具有属性的引用类型意味着您可以使用它来共享所需的任意数量的属性。请注意,对于任何共享状态,您都需要防止竞争条件。

我以相同的方式完成了 Windows 服务(多种不同的 wcf 服务类型)......这或多或少是它们共享状态的方式。

编辑:

我不知道为什么我没有早点考虑这个问题,但是另一种共享状态的好方法是使用单例。这可能比早期的方法更直接。我也有这种模式......出于不同的原因,但它也适用于共享状态:

public class SharedState
{
  //--> singleton instance...
  static readonly SharedState current;

  //--> use static initializer to create the current instance...
  static SharedState( )
  {
    current = new SharedState();
  }

  //--> hide ctor...
  private SharedState(){}

  public static SharedState Current
  {
    get { return current; }
  }

  //--> all your shared state instance methods and properties go here...

  public string SomeString
  {
    get
    {
      return //...
    }
  }

}

...然后您可以从服务中的任何位置访问此对象,甚至可以从不在客户端操作上下文中运行的代码访问。我将其用于服务需要定期执行的长时间运行的后台任务,但共享属性非常简单:

var someValue = SharedState.Current.SomeString;

推荐阅读