是否可以在接口中包装C#单例?

Sur*_*ler 11 c# singleton interface

我目前有一个类,我只有静态成员和常量,但是我想用一个包装在接口中的单例替换它.

但是我怎么能这样做,记住我见过的每个单例实现都有一个静态实例方法,从而破坏了接口规则?

Tim*_*oyd 10

要考虑(而不是自己动手)的解决方案是利用IoC容器,例如Unity.

IoC容器通常支持针对接口注册实例.这提供了您的单例行为,因为客户端解析接口将接收单个实例.

  //Register instance at some starting point in your application
  container.RegisterInstance<IActiveSessionService>(new ActiveSessionService());

  //This single instance can then be resolved by clients directly, but usually it
  //will be automatically resolved as a dependency when you resolve other types. 
  IActiveSessionService session = container.Resolve<IActiveSessionService>();
Run Code Online (Sandbox Code Playgroud)

您还可以获得额外的优势,即您可以轻松地改变单例的实现,因为它是在接口上注册的.这对于生产非常有用,但对于测试来说可能更有用.真正的单身人士在测试环境中会非常痛苦.


Try*_*ler 8

您无法使用接口执行此操作,因为它们仅指定实例方法,但您可以将其放在基类中.

单例基类:

public abstract class Singleton<ClassType> where ClassType : new()
{
  static Singleton()
  {
  }

  private static readonly ClassType instance = new ClassType();

  public static ClassType Instance
  {
    get
    {
      return instance;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

儿童单身人士:

class Example : Singleton<Example>
{
  public int ExampleProperty { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

来电者:

public void LameExampleMethod()
{
  Example.Instance.ExampleProperty++;
}
Run Code Online (Sandbox Code Playgroud)

  • `ClassType instance = new ClassType()`可以替换为`Lazy <ClassType> instance = new Lazy <ClassType>(()=> new ClassType())`用于延迟执行,当你的`ClassType`很昂贵时很有用初始化. (3认同)

Kir*_*oll 6

您可以使单例的所有其他成员在接口中实现相应的成员.但是,您是正确的,该Instance属性不能成为接口的一部分,因为它是(并且必须保持)静态.