Question

Si j'ai manqué cela dans une autre question, je m'excuse; J'ai cherché un bon moment avant de décider que j'avais une question unique ... Je veux utiliser DynamicProxy2 pour fournir une interception pour les classes de modèle d'une application WPF. C'est pour que je n'aie pas à mettre en œuvre pleinement InotifyPropertyChanged partout. Par exemple, la classe ci-dessous doit participer pleinement à la liaison des données bidirectionnelle une fois proxie et interceptée:

public class ModelExample : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

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

J'ai trouvé que je peux créer une nouvelle instance de la classe de modèle et l'intercepter les appels en appelant la méthode CreateClassProxy:

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

Malheureusement, cela m'oblige à permettre le ProxyGenerator classe pour créer mes instances de modèle, et je les récupére de mon niveau intermédiaire, c'est-à-dire qu'ils existent déjà. J'ai besoin d'envelopper des objets existants, donc je pense J'ai besoin d'appeler CreateClassProxyWithTarget Au lieu:

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

Cependant, lorsque je fais cela, mon intercepteur cesse de fonctionner. Je suis presque sûr que ce n'est pas la faute de l'intercepteur ... c'est un objet très simple. Voici son 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);
}

La FluentInterceptor Type implémente ceci. La Before, After, etc. Les méthodes sont trop simples à montrer; Ils ajoutent tous aux files d'attente qui sont destinées à être utilisées lors de l'invocation de la méthode, puis chaque méthode revient this, permettant un chaînage de méthode.

Le code ci-dessous ne fonctionne pas, mais je ne peux pas comprendre pourquoi:

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

Si j'essaye ça avec CreateClassProxy, il fonctionne comme un charme. Quelqu'un voit-il ce que je fais de mal?

Merci!

Était-ce utile?

La solution

Honnêtement, je pense que c'est un non-problème. Si jamais j'ai besoin d'un conteneur pour générer le INotifyPropertyChanged implémentation pour moi, ce sera probablement dans des cas marginaux où je branche des objets modèles qui sont construits par le conteneur de toute façon parce qu'ils ont des dépréances, etc. Dans ces cas CreateClassProxy<T>(interceptors) c'est bien. Dans tous les autres cas, j'ai utilisé MVVM ViewModels où la logique exacte entourant la notification de modification est décidée au cas par cas, l'expérience utilisateur étant au centre des choses. Les classes de modèles sont généralement aplaties ou transformées d'une manière ou d'une autre, donc tout le point est théorique. J'ai posé cette question à un moment où je ne comprenais pas comment exploiter correctement MVVM dans mon application, et je pensais que j'allais être responsable de plus de pièces mobiles. Cela a été en fait beaucoup plus facile que prévu, une fois que j'ai commencé à configurer correctement mes modes de vue.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top