【问题标题】:C# Singleton Pattern and MEFC# 单例模式和 MEF
【发布时间】:2012-01-25 21:18:23
【问题描述】:

我有一个关于单例模式和 MEF 的问题。我是实施 MEF 插件的新手,但我还没有找到答案。

是否可以通过 MEF 实现的插件只提供一个类的一个实例?

我的老班是这样的:


  #region Singleton
  /// 
  /// This class provide a generic and thread-safe interface for Singleton classes.
  /// 
  /// The specialized singleton which is derived
  /// from SingletonBase<T>
  public abstract class Base where T : Base
  {
    /* the lock object */
    private static object _lock = new object();

    /* the static instance */
    private static T _instance = null;
    /// 
    /// Get the unique instance of .
    /// This property is thread-safe!
    /// 
    public static T Instance
    {
      get
      {
        if (_instance == null)
        {
          lock (_lock)
          {
            if (_instance == null)
            {
              /* Create a object without to use new (where you need a public ctor) */
              object obj = FormatterServices.GetUninitializedObject(typeof(T));
              if (obj != null)  // just 4 safety, but i think obj == null shouldn't be possible
              {
                /* an extra test of the correct type is redundant,
                 * because we have an uninitialised object of type == typeof(T) */
                _instance = obj as T;
                _instance.Init(); // now the singleton will be initialized
              }
            }
          }
        }
        else
        {
          _instance.Refresh();  // has only effect if overridden in sub class
        }
        return _instance;
      }
    }


    /// 
    /// Called while instantiation of singleton sub-class.
    /// This could be used to set some default stuff in the singleton.
    /// 
    protected virtual void Init()
    { }

    /// 
    /// If overridden this will called on every request of the Instance but
    /// the instance was already created. Refresh will not called during
    /// the first instantiation, for this will call Init.
    /// 
    protected virtual void Refresh()
    { }
  }
  #endregion

  #region class
  public class xy : Base
  {
    private bool run;

    public xy()
    {
      this.run = false;
    }

    public bool isRunning()
    {
      return this.run;
    }

    public void start()
    {
      // Do some stuff
      this.run = true;
    }
  }
  #endregion

谁能给我一个例子?

【问题讨论】:

标签: c# singleton mef


【解决方案1】:

是的,可以这样做。

默认情况下,MEF 在填充您的导入时将始终返回相同的类实例。所以从技术上讲,如果你想让它成为一个单例,你不必做任何事情。这就是 MEF 所说的共享创建策略。

如果你不希望你的导入来自同一个实例,你需要在你的属性中指定它:

[Import(RequiredCreationPolicy = CreationPolicy.NonShared)]
public MyClass : IMyInterface

或者您可以覆盖您自己的 CompositionContainer,以便默认创建 NonShared 实例。

请注意,您还可以明确指定您需要共享创建策略(单例):

[Import(RequiredCreationPolicy = CreationPolicy.Shared)]
public MyClass : IMyInterface
{
    public MyClass() { } // you can have a public ctor, no need to implement the singleton pattern 
}

但没有必要,因为 Shared (singleton) 已经是默认值了。

这里是 MEF 文档的链接:http://mef.codeplex.com/wikipage?title=Parts%20Lifetime,它解释了我刚才谈到的内容。您还可以通过搜索“MEF Creation Policy”找到有关该主题的博客。

【讨论】:

  • Gilles 关于 MEF 在 CreationPolicy 方面的行为方式是绝对正确的。只是想我要指出的是,您使用单例模式获得的单实例保证在这里没有严格执行,因为有人仍然可以在 MEF 之外新建另一个实例。
【解决方案2】:

非常糟糕的做法!使用静态构造函数: 保证只执行一次

请注意,对于您创建的每个T,CLR 将为新的T 复制静态数据。

因此,您正在为您使用的每个 T 类型创建一个单例。

单例的最佳方式是这样的:

public class Logger {
    public static readonly Logger Instace;

    static Logger() {
        Instace = new Logger();
    }
}

【讨论】:

  • 嗨,非常感谢您的快速回答,但我如何将它与 MEF 一起使用?
  • 您可以将它与 MEF 一起使用。像往常一样把 MEF 一切都搞好,然后当 MEF FIRST 初始化类时调用静态构造函数。
猜你喜欢
  • 2023-04-08
  • 2013-07-01
  • 2014-06-05
  • 2010-11-03
  • 1970-01-01
相关资源
最近更新 更多