Create mobile apps with HTML5, JavaScript and Visual Studio

(Elle) #1

msdnmagazine.com February 2014 65


Now you need to make the change in only one place, but you still


need to change the class every time you want to change the fi lter.


One solution to this would be to expose the fi lter as a class property,


so you can assign the responsibility of creating a fi lter to the caller.


You can create a Filter property of type Predicate


and use it to fi lter the data, as shown in Figure 15.


Th e Filter property is initialized with Filter = m => true. Th at


means there’s no fi lter active. When assigning the Filter property,


the program verifies if the value is null and, if so, it resets the


filter. In the Invoke method execution, the program checks the


fi lter result and, if true, it applies the aspect. Now the proxy cre-


ation in the factory class looks like this:


public class RepositoryFactory
{
public static IRepository<T> Create<T>()
{
var repository = new Repository<T>();
var dynamicProxy = new DynamicProxy<IRepository<T>>(repository)
{
Filter = m => !m.Name.StartsWith("Get")
};
return dynamicProxy.GetTransparentProxy() as IRepository<T>;
}
}
}

Th e responsibility of creating the fi lter has been transferred to


the factory. When you run the program, you should get something


like Figure 16.


Notice in Figure 16 that the last two methods, GetAll and


GetById (represented by “Getting entities” and “Getting entity 1”)


don’t have logging around them. You can enhance the class even


further by exposing the aspects as events. Th at way, you don’t have


to change the class every time you want to change the aspect. Th is


is shown in Figure 17.


In Figure 17, three events, BeforeExecute, AfterExecute and


ErrorExecuting, are called by the methods OnBeforeExecute,


OnAft erExecute and OnErrorExecuting. Th ese methods verify whether


the event handler is defi ned and, if it is, they check if the called


method passes the fi lter. If so, they call the event handler that applies


the aspect. Th e factory class now becomes something like Figure 18.


Now you have a flexible proxy class, and you can choose the


aspects to apply before executing, aft er executing or when there’s


an error, and only for selected methods. With that, you can apply


many aspects in your code with no repetition, in a simple way.


Not a Replacement


With AOP you can add code to all layers of your application in a


centralized way, with no need to repeat code. I showed how to cre-


ate a generic dynamic proxy based on the Decorator design pattern


that applies aspects to your classes using events and a predicate to


fi lter the functions you want.


As you can see, the RealProxy class is a fl exible class and gives


you full control of the code, with no external dependencies. How-


Figure 1 6 Output with a Filtered Proxy


Figure 15 A Filtering Proxy


class DynamicProxy<T> : RealProxy
{
private readonly T _decorated;
private Predicate<MethodInfo> _filter;

public DynamicProxy(T decorated)
: base(typeof(T))
{
_decorated = decorated;
_filter = m => true;
}

public Predicate<MethodInfo> Filter
{
get { return _filter; }
set
{
if (value == null)
_filter = m => true;
else
_filter = value;
}
}

private void Log(string msg, object arg = null)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(msg, arg);
Console.ResetColor();
}

public override IMessage Invoke(IMessage msg)
{
var methodCall = msg as IMethodCallMessage;
var methodInfo = methodCall.MethodBase as MethodInfo;

if (_filter(methodInfo))
Log("In Dynamic Proxy - Before executing '{0}'",
methodCall.MethodName);

try
{
var result = methodInfo.Invoke(_decorated, methodCall.InArgs);
if (_filter(methodInfo))
Log("In Dynamic Proxy - After executing '{0}' ",
methodCall.MethodName);

return new ReturnMessage(result, null, 0,
methodCall.LogicalCallContext, methodCall);
}
catch (Exception e)
{
if (_filter(methodInfo))
Log(string.Format(
"In Dynamic Proxy- Exception {0} executing '{1}'", e),
methodCall.MethodName);
return new ReturnMessage(e, methodCall);
}
}
}
Free download pdf