2014-02-27 1 views
0

나는 이것을 수행하는 방법에 대한 답변으로 몇 개의 게시물을 보았습니다. 답변은 모두 사전에 액션을 배치하는 것에 의존했습니다. 그러나 문제는 사전에없는 메서드에 알 수없는 서명이있는 작업을 전달해야한다는 것입니다.C#에서 알 수없는 서명이있는 메소드에 대한 참조를 저장합니다.

다음 방법을 사용하는 기존 코드가 있습니다. 오버로드를 추가하여 기존 코드와의 호환성을 유지할 수 있습니다.

// Collection of notification observers. 
    private static Dictionary<string, List<NotificationObserver>> _Observers = new Dictionary<string, List<NotificationObserver>>(); 
    public static SynchronizationContext Context { get; set; } 

    public static void RegisterObserver(object observer, string notification, Action<object, Dictionary<string, object>> action) 
    { 
     // We only register valid objects. 
     if (string.IsNullOrWhiteSpace(notification) || action == null || observer == null) return; 

     // Create a new NotificationObserver object. 
     // Currently you provide it a reference to the observer. This is not used anywhere; there are plans to use this. 
     var registeredObserver = new NotificationObserver(observer, action); 

     // Make sure the notification has already been registered. 
     // If not, we add the notification to the dictionary, then add the observer. 
     if (_Observers.ContainsKey(notification)) 
      _Observers[notification].Add(registeredObserver); 
     else 
     { 
      var observerList = new List<NotificationObserver>(); 
      observerList.Add(registeredObserver); 
      _Observers.Add(notification, observerList); 
     } 
    } 

    public static void PostNotification(object sender, string notification, Dictionary<string, object> userData = null) 
    { 
     // Make sure the notification exists. 
     if (_Observers.ContainsKey(notification)) 
     { 
      // Loop through each objects in the collection and invoke their methods. 
      foreach (NotificationObserver observer in _Observers[notification].Where(obs => obs != null)) 
      { 
       if (Context == null) 
        observer.Action(sender, userData); 
       else 
       { 
        Context.Send((state) => observer.Action(sender, userData), null); 
       } 
      } 

      // Clean ourself up. 
      Task.Run(new Action(() => 
      { 
       PurgeNullObservers(); 
      })); 
     } 
    } 

내 코드베이스에서 다음 내가 뭘하고 싶은 것은

internal sealed class NotificationObserver 
{ 
    internal NotificationObserver(object observer, Action<object, Dictionary<string, object>> action) 
    { 
     this.Observer = observer; 
     this.Action = action; 
    } 

    internal object Observer { get; private set; } 
    internal Action<object, Dictionary<string, object>> Action { get; private set; } 

} 

알림 관찰자 : 기본적으로

NotificationManager.RegisterObserver(this.SomeProperty, "SomeString", this.SomeProperty.DoStuff); 
NotificationManager.RegisterObserver(this.Logger, "LogInfo", this.Logger.LogInfo); 

, 나는 제 3 자 라이브러리 오브젝트에 대한 지원을 제공 할 소스 코드에 액세스 할 수 없으며 미리 정의 된 액션 서명과 일치하는 메소드를 추가 할 수 없습니다. 또한 다양한 서명 변형 톤에 대해 30 오버로드를 원하지 않습니다.

누구나이를 달성하기위한 적절한 방법을 알고 계십니까? 내가 할 수있는 RegisterObserver와 NotificationObserver를 수정해야한다면, 기존의 메소드 시그니처를 수정하지 않고 과부하를 추가하지 않고도 할 수 있기를 바랬다.

미리 감사드립니다.

답변

1

RegisterObserver 호출을 생성 할 때 람다 표현식을 사용하지 않는 이유는 무엇입니까?

NotificationManager.RegisterObserver(this.ThirdParty, 
    "ThirdPartyData", 
    (i,j) => 
     { 
      // call the third party method 
      this.ThirdParty.ThirdPartyMethod(null, false, i); 
      // other custom logic here using j (the action dictionary) 
     }); 

제 3 자 호출을 기존 서명과 호환되도록 '조정'하는 데 필요한 정보가 있으면 문제가 없습니다. 람다 식으로 작성된 클로저의 모든 정보를 자동으로 캡처합니다.

+0

감사합니다. 나는이 저택에서 그것을 수행하는 것을 고려하지 않았습니다. 이것은 완벽하게 이해하고 정확히 필요한 방식으로 작업했습니다. 감사! –

관련 문제