http://msdn.microsoft.com/en-us/library/ff660851(v=PandP.20).aspx fournit un exemple d'implémentation de IInterceptionBehavior pour ajouter le support INotifyPropertyChanged. Ce que l'exemple ne comprend pas, c'est comment configurer NotifyPropertyChangedBehavior pour être utilisé lors de l'exécution. Tout le googling que j'ai fait ne m'a pas donné une réponse de travail. Je suis nouveau à l'AOP et à l'IoC donc peut-être que j'ai aussi le concept faux. Voilà ce que je veux faire:Comment configurer Unity 2.0 à l'exécution pour intercepter INotifyPropertyChanged?
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.InterceptionExtension;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
static class AppMain
{
public static void Main()
{
// Configure Unity.
var container = new UnityContainer();
container.AddNewExtension<Interception>();
// todo: Register an interface instead of a type.
container.RegisterType<Customer>(new Interceptor<VirtualMethodInterceptor>(),
new InterceptionBehavior<NotifyPropertyChangedBehavior>());
var propertyChangedCount = 0;
var customer = new Customer();
customer.PropertyChanged += (s, e) => propertyChangedCount += 1;
// Update customer and send property changed event.
customer.FirstName = "what ever";
if (propertyChangedCount != 1)
{
Console.Write("Failed!");
}
else
{
Console.WriteLine("Success!");
}
Console.WriteLine();
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
}
static void customer_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
throw new NotImplementedException();
}
public class Customer : MarshalByRefObject, INotifyPropertyChanged
{
private string _firstName;
public event PropertyChangedEventHandler PropertyChanged;
// todo: Does the property have to be virtual (overridable).
public virtual string FirstName
{
get { return _firstName; }
set
{
_firstName = value;
// Unity Interception to do the following RaiseEvent
//if (PropertyChanged != null)
//{
// PropertyChanged(this, new PropertyChangedEventArgs("FirstName"));
//}
}
}
}
// Copied from http://msdn.microsoft.com/en-us/library/ff660851(v=PandP.20).aspx
class NotifyPropertyChangedBehavior : IInterceptionBehavior
{
private event PropertyChangedEventHandler propertyChanged;
private static readonly MethodInfo addEventMethodInfo =
typeof(INotifyPropertyChanged).GetEvent("PropertyChanged").GetAddMethod();
private static readonly MethodInfo removeEventMethodInfo =
typeof(INotifyPropertyChanged).GetEvent("PropertyChanged").GetRemoveMethod();
public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
{
if (input.MethodBase == addEventMethodInfo)
{
return AddEventSubscription(input, getNext);
}
if (input.MethodBase == removeEventMethodInfo)
{
return RemoveEventSubscription(input, getNext);
}
if (IsPropertySetter(input))
{
return InterceptPropertySet(input, getNext);
}
return getNext()(input, getNext);
}
public bool WillExecute
{
get { return true; }
}
public IEnumerable<Type> GetRequiredInterfaces()
{
return new[] { typeof(INotifyPropertyChanged) };
}
private IMethodReturn AddEventSubscription(IMethodInvocation input,
GetNextInterceptionBehaviorDelegate getNext)
{
var subscriber = (PropertyChangedEventHandler)input.Arguments[0];
propertyChanged += subscriber;
return input.CreateMethodReturn(null);
}
private IMethodReturn RemoveEventSubscription(IMethodInvocation input,
GetNextInterceptionBehaviorDelegate getNext)
{
var subscriber = (PropertyChangedEventHandler)input.Arguments[0];
propertyChanged -= subscriber;
return input.CreateMethodReturn(null);
}
private static bool IsPropertySetter(IMethodInvocation input)
{
return input.MethodBase.IsSpecialName && input.MethodBase.Name.StartsWith("set_");
}
private IMethodReturn InterceptPropertySet(IMethodInvocation input,
GetNextInterceptionBehaviorDelegate getNext)
{
var propertyName = input.MethodBase.Name.Substring(4);
var returnValue = getNext()(input, getNext);
var subscribers = propertyChanged;
if (subscribers != null)
{
subscribers(input.Target, new PropertyChangedEventArgs(propertyName));
}
return returnValue;
}
}
}
Votre code compile et fonctionne apparemment, mais l'événement PropertyChanged n'est pas soulevé par le client comme prévu . J'ai changé le code source en C#. Cela semble conduire à plus de personnes lisant un message. –
Trouvé l'erreur, l'intercepteur doit être TransparentProxyInterceptor, pas VirtualMethodInterceptor. – onof