如何在本地计算机上安装的多个 WCF 服务之间共享 属性?

How to share a property between multiple WCF services installed on a local machine?

我有一个 Windows 服务托管多个 WCF 服务。所有这些 运行 在本地机器上(使用 NamePipe)。
有没有一种简单的方法可以让这些 WCF 服务共享一个 属性? (我宁愿不让他们共享一个文件)。
我需要这个,因为在每个 WCF 服务中实例化的每个会话都将在给定的硬件上保持不变,而其他 WCF 服务需要知道什么仍然可用,以便能够实例化另一个会话。
每个 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 的地方,您可以将其设为您想要的任何类型...但是将其设为 本身 具有属性的引用类型意味着您可以使用它来共享您需要的尽可能多的属性。请注意,使用 any 共享状态,您将有竞争条件来防止。

我以相同的方式完成了一项 windows 服务(多种不同的 wcf 服务类型)...这就是 more-or-less 它们共享状态的方式。

编辑:

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

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;