DynamicProxy2: CreateClassProxyWithTarget + IInterceptor - PullRequest
0 голосов
/ 16 мая 2011

Если я пропустил это в другом вопросе, я прошу прощения; Я долго искал, прежде чем решил, что у меня возник уникальный вопрос ... Я хочу использовать DynamicProxy2, чтобы обеспечить перехват для классов моделей приложения WPF. Это связано с тем, что мне не нужно полностью внедрять INotifyPropertyChanged везде. Например, приведенный ниже класс должен полностью участвовать в двустороннем связывании данных после того, как прокси и перехвачен:

public class ModelExample : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

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

Я обнаружил, что могу создать новый экземпляр класса модели и перехватить вызовы к нему, вызвав метод CreateClassProxy:

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

К сожалению, это вынуждает меня разрешить классу ProxyGenerator создавать экземпляры моей модели, и я получаю их обратно со своего среднего уровня, то есть они уже существуют. Мне нужно обернуть существующие объекты, поэтому я думаю Мне нужно вместо этого вызвать CreateClassProxyWithTarget:

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

Однако, когда я это делаю, мой перехватчик перестает функционировать. Я уверен, что это не вина перехватчика ... это очень простой объект. Вот его интерфейс:

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);
}

Тип FluentInterceptor реализует это. Методы Before, After и т. Д. Слишком просты для показа; все они добавляют к очередям действий, предназначенным для использования во время вызова метода, затем каждый метод возвращает this, что обеспечивает цепочку методов.

Приведенный ниже код не работает, но я не могу понять, почему:

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));
    }));

Если я попробую это с CreateClassProxy, это будет работать как шарм. Кто-нибудь видит, что я делаю не так?

Спасибо!

1 Ответ

2 голосов
/ 02 января 2012

Честно говоря, я думаю, что это не проблема.Если мне когда-нибудь понадобится контейнер для генерации реализации INotifyPropertyChanged, то, вероятно, это будет в некоторых случаях, когда я подключаю объекты модели, которые все равно создаются контейнером, потому что они имеют зависимости и т. Д.1002 * хорошо.Во всех других случаях я использовал MVVM ViewModels, где точная логика, связанная с уведомлением об изменениях, определяется в каждом конкретном случае, с фокусом на опыте пользователя.Классы моделей обычно каким-то образом сглаживаются или трансформируются, поэтому все дело в споре.Я задал этот вопрос в то время, когда я не понимал, как правильно использовать MVVM в своем приложении, и я подумал, что буду отвечать за большее количество движущихся частей.На самом деле все оказалось намного проще, чем предполагалось, когда я начал правильно настраивать свои ViewModels.

...