开发者

Attaching to a factory instantiated singleton event - what would be a clean approach?

In my program, there is a place when I need to access a singleton resolved from a factory and attach to its event:

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

The problem is that MyMethod can be executed multiple times, but I want to attach to event only 开发者_如何学编程once (otherwise I'll get multiple calls). So I want to attach only when I wasn't attached before. It there anything nicier than

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


What about some flag to remember if MyMethod has already been called for the singleton?

object myCachedSingleton = null;

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


Depending on how coupled you want these types to be, you could attach to the event in a static constructor. Then it would only be possible to get executed a single time (per AppDomain I think). Something like this:

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

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

The (over) use of static methods is a little off-putting, but depending on your requirements that may be ok.

I'll just add that the other answers here are also fine, but make sure you think about any threading issues.


You could also look into the InvocationList to see if anything has been attached to the event.

Edited to use an Action so you don't need to pass in some magic string.

Example:

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

Usage:

    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));

Output would be true, true, false


I just want to put the approach I used in the question for voting, too - if you disagree, vote it down...

Is there anything wrong with

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

???

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜