Присоединение к синглтон-событию, созданному на заводе-изготовителе, - какой будет чистый подход? - PullRequest
1 голос
/ 13 ноября 2009

В моей программе есть место, где мне нужно получить доступ к синглтону, разрешенному с завода, и присоединиться к его событию:

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

Проблема в том, что MyMethod может быть выполнен несколько раз, но я хочу присоединиться к событию только один раз (в противном случае я получу несколько вызовов). Поэтому я хочу присоединиться только тогда, когда я не был привязан раньше. Там что-нибудь лучше, чем

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

Ответы [ 4 ]

5 голосов
/ 13 ноября 2009

Как насчет флага, который нужно запомнить, если MyMethod уже был вызван для синглтона?

object myCachedSingleton = null;

void MyMethod()
{
    var s = myFactory.Resolve<MySingleton>();
    if (myCachedSingleton == s) return;
    myCachedSingleton = s;
    myCachedSingleton.DoWork += WorkMethod;
}
1 голос
/ 13 ноября 2009

В зависимости от того, насколько вы хотите связать эти типы, вы можете присоединиться к событию в статическом конструкторе. Тогда было бы возможно выполнить только один раз (для AppDomain, я думаю). Примерно так:

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

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

(чрезмерное) использование статических методов немного отталкивает, но в зависимости от ваших требований это может быть нормально.

Я просто добавлю, что другие ответы здесь также хороши, но убедитесь, что вы думаете о любых проблемах с потоками.

0 голосов
/ 13 ноября 2009

Я просто хочу поставить подход, который я использовал в вопросе, тоже для голосования - если вы не согласны, проголосуйте ...

Что-то не так с

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

???

0 голосов
/ 13 ноября 2009

Вы также можете заглянуть в InvocationList, чтобы узнать, было ли что-либо прикреплено к событию.

Отредактировано для использования действия, поэтому вам не нужно передавать какую-то магическую строку.

Пример:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...