代码之家  ›  专栏  ›  技术社区  ›  Sergey Aldoukhov

附加到工厂实例化的单例事件-什么是干净的方法?

  •  1
  • Sergey Aldoukhov  · 技术社区  · 14 年前

    在我的程序中,有一个地方需要访问工厂解析的单例并附加到它的事件:

    void MyMethod()
    {
       myFactory.Resolve<MySingleton>().DoWork += WorkMethod;
    }
    

    问题是MyMethod可以执行多次,但我只想附加到事件一次(否则我将得到多个调用)。所以我只想在我以前没有被附加的时候附加。 有比这更好的吗

       myFactory.Resolve<MySingleton>().DoWork -= WorkMethod;
       myFactory.Resolve<MySingleton>().DoWork += WorkMethod;
    
    4 回复  |  直到 14 年前
        1
  •  5
  •   dtb    14 年前

    如果有什么旗子要记住呢 MyMethod 已经要求单打了吗?

    object myCachedSingleton = null;
    
    void MyMethod()
    {
        var s = myFactory.Resolve<MySingleton>();
        if (myCachedSingleton == s) return;
        myCachedSingleton = s;
        myCachedSingleton.DoWork += WorkMethod;
    }
    
        2
  •  1
  •   akmad    14 年前

    根据您希望这些类型如何耦合,可以在静态构造函数中附加到事件。然后只能执行一次(我认为是按AppDomain执行)。像这样:

    public class MyConsumer
    {
        static MyConsumer()
        {
            Factory.Resolve<Singleton>().DoWork += WorkMethod;
        }
    
        private static void WorkMethod(...) { ... }
    }
    

    静态方法的(过度)使用有点令人不快,但取决于您的需求,这可能是可以的。

    我要补充的是,这里的其他答案也很好,但是要确保您考虑到任何线程问题。

        3
  •  0
  •   Mark Coleman    14 年前

    您还可以查看调用列表,查看是否有任何附加到事件的内容。

    编辑以使用一个动作,这样您就不需要传入一些魔术字符串。

    例子:

    public bool IsAttached(Action<string> methodToCheck)
    {
        SomeWork completed = DoWork;
        return completed.GetInvocationList().Any(m => m.Method.Name == methodToCheck.Method.Name);
    }
    

    用途:

        var b = new FooBar();
        b.DoWork += b_OnWorkCompleted;
        b.DoWork += c_OnWorkCompleted;
    
        Console.WriteLine(b.IsAttached(c_OnWorkCompleted));
        Console.WriteLine(b.IsAttached(b_OnWorkCompleted));
        Console.WriteLine(b.IsAttached(FooBar));
    

    输出将是 true, true, false

        4
  •  0
  •   Sergey Aldoukhov    14 年前

    我只想把我在这个问题上使用的投票方法也放在一边-如果你不同意,就把它投下来…

    有什么问题吗

    var singleton = myFactory.Resolve<MySingleton>();
    singleton.DoWork -= WorkMethod;   
    singleton.DoWork += WorkMethod;
    

    ????