English 中文(简体)
Attaching to a factory instantiated singleton event - what would be a clean approach?
原标题:
  • 时间:2009-11-13 17:48:26
  •  标签:
  • c#
  • events

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;

???





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签