Another way to do this is to use an interception similar to that provided by the Unity infrastructure. With a hook, your class implements the interface, and you tell the framework that each time the method is called in classes that implement this interface, run these hooks. Your interceptor code can see if there is a method that is being called with the set_ prefix. The interceptor code is executed once on the function path and once on the return path. On the way back, you can force the interceptor to call the filter method (provided that it is defined on the interface, of course).
Specific example:
Get Preliminary Library
Use NuGet to Add Unity and Unity Extensions to Your Project
Define an interface to intercept: SomeObject.cs
using System; namespace InterceptSetter { interface ISomeObject { string SomeProperty { get; set; } void Filter(); } public class SomeObject : ISomeObject { public string SomeProperty { get; set; } public void Filter() { Console.Out.WriteLine("Filter Called"); } } }
Define interception behavior: SetterCallsFilterMethodBehavior.cs
using Microsoft.Practices.Unity.InterceptionExtension; using System; using System.Collections.Generic; using System.Linq; namespace InterceptSetter { /// <summary> /// See http://msdn.microsoft.com/en-us/library/ff660871(v=pandp.20).aspx /// See http://msdn.microsoft.com/en-us/library/ff647107.aspx /// </summary> class SetterCallsFilterMethodBehavior : IInterceptionBehavior { public IEnumerable<Type> GetRequiredInterfaces() { // we dont need anything return new[] { typeof(ISomeObject) }; } public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext) { // Do not intercept non-setter methods if (!input.MethodBase.Name.StartsWith("set_")) return getNext()(input, getNext); IMethodReturn msg = getNext()(input, getNext); // post processing. this is where we call filter if (input.Target is ISomeObject) { (input.Target as ISomeObject).Filter(); } return msg; } /// <summary> /// We always execute /// </summary> public bool WillExecute { get { return true; } } } }
Record Test Console Program: Program.cs
using Microsoft.Practices.Unity; using Microsoft.Practices.Unity.InterceptionExtension; using System; namespace InterceptSetter { class Program { static void Main(string[] args) { UnityContainer container = new UnityContainer(); container.AddNewExtension<Interception>(); container.RegisterType<ISomeObject, SomeObject>( new Interceptor<TransparentProxyInterceptor>(), new InterceptionBehavior<SetterCallsFilterMethodBehavior>());
By running this, you will see that the interceptor actually calls the filter method (which prints to the console).
Unity is not the only dependency injection / interception framework (google PostSharp). Unity is the one I am familiar with, so this is an example of use.
Sources / See also:
Steven magana-zook
source share