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

时间:2009-11-13 17:48:26

标签: c# events

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

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

问题是MyMethod可以多次执行,但我想只附加一次事件(否则我会接到多次调用)。所以我只想在以前没有依恋的时候才能附上。 它有什么比

更好的东西
   myFactory.Resolve<MySingleton>().DoWork -= WorkMethod;
   myFactory.Resolve<MySingleton>().DoWork += WorkMethod;

4 个答案:

答案 0 :(得分:5)

如果已经为单身人士调用了MyMethod,那么要记住一些标志呢?

object myCachedSingleton = null;

void MyMethod()
{
    var s = myFactory.Resolve<MySingleton>();
    if (myCachedSingleton == s) return;
    myCachedSingleton = s;
    myCachedSingleton.DoWork += WorkMethod;
}

答案 1 :(得分:1)

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

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

    private static void WorkMethod(...) { ... }
}

(过度)使用静态方法有点令人反感,但根据您的要求可能没问题。

我只想补充一点,这里的其他答案也很好,但请确保您考虑任何线程问题。

答案 2 :(得分:0)

您还可以查看InvocationList以查看是否有任何事件附加到该事件。

编辑使用Action,因此您无需传入一些魔术字符串。

示例:

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

答案 3 :(得分:0)

我只是想把我在问题中使用的方法用于投票 - 如果你不同意,请将其投票......

有什么问题吗?
var singleton = myFactory.Resolve<MySingleton>();
singleton.DoWork -= WorkMethod;   
singleton.DoWork += WorkMethod;

???