2017-08-04 81 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(); 
}