2017-08-04 73 views
0

在我們的應用程序之一,我們有一個這樣的(現有的)接口:遠程與代表

public interface INotify 
{ 
    void RegisterNotification(Action<int, string> notification); 
} 

現在我們要實現使用IpcChannels一個「遠程層」實現此接口的對象。
我閱讀了很多關於遠程處理,代表和事件的文章,但無法獲得測試場景的工作。大多數示例使用直接在服務器類中實現的事件,而不是參數中的委託。
有人知道一個工作示例或給我一個提示嗎?

通過創建一個「EventSink」並使用Expression lambda表達式重新創建委託來製作它。似乎有點複雜,但工作...

+0

你在[MSDN ](https://msdn.microsoft.com/en-us/library/system.runtime.remoting.channels.ipc.ipcchannel(v = vs.110).aspx)一些例子,但爲什麼你需要使用IPC? – Ygalbel

+0

感謝您的提示。 我們需要使用遠程處理和IPC,因爲我們想要使用INativeHandleContract作爲應用程序中使用的遠程創建的wpf控件(AddIn機制)。 – chrisih

回答

0

的EventSink的:

public class GenericEventSink : MarshalByRefObject 
{ 
    public event GenericDelegate MessageReceived; 

    public Type OriginalType { get; } 

    public GenericEventSink(Delegate original) 
    { 
    OriginalType = original.GetType(); 
    MessageReceived += objects => 
    { 
     try 
     { 
     return original.DynamicInvoke(objects); 
     } 
     catch (Exception ex) 
     { 
     return null; 
     } 
    }; 
    } 

    public override object InitializeLifetimeService() 
    { 
    return null; 
    } 

    public object OnMessageReceived0() 
    { 
    return MessageReceived?.Invoke(); 
    } 
    public object OnMessageReceived1(object o1) 
    { 
    return MessageReceived?.Invoke(o1); 
    } 
    public object OnMessageReceived2(object o1, object o2) 
    { 
    return MessageReceived?.Invoke(o1, o2); 
    } 
    public object OnMessageReceived3(object o1, object o2, object o3) 
    { 
    return MessageReceived?.Invoke(o1, o2, o3); 
    } 
} 

...並重新創建委託方法被調用:

private object UnmarshalDelegate(GenericEventSink generic) 
{ 
    var pars = generic.OriginalType.GenericTypeArguments.Select(Expression.Parameter).ToArray(); 

    // create the call 
    var method = generic.GetType().GetMethod("OnMessageReceived" + pars.Length); 
    var call = Expression.Call(Expression.Constant(generic), method, pars.Select(p => Expression.Convert(p, typeof(object)))); 
    return Expression.Lambda(generic.OriginalType, call, pars).Compile(); 
}