简体   繁体   English

DynamicProxy2:CreateClassProxyWithTarget + IInterceptor

[英]DynamicProxy2: CreateClassProxyWithTarget + IInterceptor

If I've missed this in another question I apologize; 如果我在另一个问题中错过了这个,我道歉; I looked for a good while before deciding I had a unique question... I want to use DynamicProxy2 to provide interception for a WPF application's model classes. 在决定我有一个独特的问题之前,我找了好一会儿...我想使用DynamicProxy2为WPF应用程序的模型类提供拦截。 This is so that I do not have to fully implement INotifyPropertyChanged everywhere. 这样我就不必在任何地方完全实现INotifyPropertyChanged。 For instance, the below class should fully participate in two-way data binding once proxied and intercepted: 例如,下面的类应该在代理和截获后完全参与双向数据绑定:

public class ModelExample : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public int Id{ get; set; }
    public string Uri{ get; set; }
    public string Name{ get; set; }
}

I have found that I can create a new instance of the model class and intercept calls to it by calling the CreateClassProxy method: 我发现我可以通过调用CreateClassProxy方法创建模型类的新实例并拦截对它的调用:

new ProxyGenerator().CreateClassProxy<T>(interceptors);

Unfortunately, this forces me to allow the ProxyGenerator class to create my model instances, and I'm getting those back from my middle tier, ie they already exist. 不幸的是,这迫使我允许ProxyGenerator类创建我的模型实例,并且我从中间层获取它们,即它们已经存在。 I need to wrap existing objects, so I think I need to call CreateClassProxyWithTarget instead: 我需要包装现有对象,所以我认为我需要调用CreateClassProxyWithTarget

new ProxyGenerator().CreateClassProxyWithTarget(instance, interceptors);

However, when I do that my interceptor stops functioning. 但是,当我这样做时,我的拦截器停止运作。 I'm pretty sure it's not the interceptor's fault... it's a very simple object. 我很确定这不是拦截器的错...它是一个非常简单的对象。 Here's its interface: 这是它的界面:

public interface IFluentInterceptor : IInterceptor
{
    IFluentInterceptor Before(Action<IInvocation> before);
    IFluentInterceptor After(Action<IInvocation> after);
    IFluentInterceptor Finally(Action<IInvocation> @finally);
    IFluentInterceptor RunCondition(Func<IInvocation, bool> runCondition);
    IFluentInterceptor OnError(Func<IInvocation, Exception, bool> onError);
}

The FluentInterceptor type implements this. FluentInterceptor类型实现了这一点。 The Before , After , etc. methods are too simple to show; BeforeAfter等方法太简单了; they all add to action queues that are meant to be used during method invocation, then each method returns this , allowing for method chaining. 它们都添加到在方法调用期间要使用的操作队列,然后每个方法返回this ,允许方法链接。

The below code doesn't work, but I can't figure out why: 以下代码不起作用,但我无法弄清楚原因:

new ProxyGenerator().CreateClassProxyWithTarget(instance, new FluentInterceptor()
    .After(invocation =>
    {
        if (!invocation.Method.Name.StartsWith("set_")) return;
        string propertyName = invocation.Method.Name.Substring(4);
        FieldInfo info = invocation.TargetType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic)
            .Where(f => f.FieldType.Equals(typeof (PropertyChangedEventHandler)))
            .FirstOrDefault();
        if (info == null) return;
        var handler = info.GetValue(invocation.InvocationTarget) as PropertyChangedEventHandler;
        if (handler != null) handler.Invoke(invocation.TargetType, new PropertyChangedEventArgs(propertyName));
    }));

If I try that with CreateClassProxy , it works like a charm. 如果我尝试使用CreateClassProxy ,它就像一个魅力。 Does anybody see what I'm doing wrong? 有人看到我做错了吗?

Thanks! 谢谢!

Honestly, I think this is a non-issue. 老实说,我认为这不是问题。 If I ever need a container to generate the INotifyPropertyChanged implementation for me, it'll probably be in fringe cases where I'm plugging in model objects that get built by the container anyway because they have depedencies, etc. In those cases CreateClassProxy<T>(interceptors) is fine. 如果我需要一个容器来为我生成INotifyPropertyChanged实现,它可能会在我插入由容器构建的模型对象的边缘情况下,因为它们具有依赖性等。在这些情况下CreateClassProxy<T>(interceptors)很好。 In all other cases I have been using MVVM ViewModels where the exact logic surrounding change notification is decided on a case-by-case basis, with the user experience being the focus. 在所有其他情况下,我一直在使用MVVM ViewModels,其中围绕变更通知的确切逻辑是根据具体情况决定的,以用户体验为重点。 Model classes usually get flattened or transformed in some way, so the whole point is moot. 模型类通常会以某种方式变平或变换,因此整点都没有实际意义。 I asked this question at a time when I didn't understand how to properly leverage MVVM in my app, and I thought I was going to be responsible for more moving parts. 当我不明白如何在我的应用程序中正确利用MVVM时,我问过这个问题,而且我认为我将负责更多移动部件。 It's actually been a lot easier than anticipated, once I started configuring my ViewModels properly. 一旦我开始正确配置我的ViewModel,它实际上比预期容易得多。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM