Create mobile apps with HTML5, JavaScript and Visual Studio

(Elle) #1

62 msdn magazine Aspect-Oriented Programming



  • You could inherit a new class and add the new functionality,


but that may result in many new classes. For example, let’s


say you have a repository class for create, read, update and


delete (CRUD) database operations and you want to add


auditing. Later, you want to add data validation to be sure


the data is being updated correctly. Aft er that, you might


also want to authenticate the access to ensure that only


authorized users can access the classes. These are big


issues: You could have some classes that implement all three


aspects, and some that implement only two of them or even


only one. How many classes would you end up having?



  • You can “decorate” the class with the aspect, creating a new


class that uses the aspect and then calls the old one. Th at way,


if you need one aspect, you decorate it once. For two aspects,


you decorate it twice and so on. Let’s say you order a toy (as


we’re all geeks, an Xbox or a smartphone is OK). It needs a


package for display in the store and for protection. Th en, you


order it with gift wrap, the second decoration, to embellish the


box with tapes, stripes, cards and gift paper. Th e store sends the


toy with a third package, a box with Styrofoam balls for pro-


tection. You have three decorations, each one with a diff erent


functionality, and each one independent from one another.


You can buy your toy with no gift packaging, pick it up at the


store without the external box or even buy it with no box (with a


special discount!). You can have your toy with any combination


of the decorations, but they don’t change its basic functionality.


Now that you know about the Decorator pattern, I’ll show how


to implement it in C#.


First, create an interface IRepository:


public interface IRepository<T>
{
void Add(T entity);
void Delete(T entity);
void Update(T entity);
IEnumerable<T> GetAll();
T GetById(int id);
}

Implement it with the Repository class, shown in Figure 1.


Use the Repository class to add, update, delete and retrieve


the elements of the Customer class:
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
}

Th e program could look something like Figure 2.


When you run this code, you’ll see something like Figure 3.


Imagine your boss asks you to add logging to this class.


You can create a new class that will decorate IRepository.


It receives the class to build and implements the same


interface, as shown in Figure 4.


Th is new class wraps the methods for the decorated


class and adds the logging feature. You must change the


code a little to call the logging class, as shown in Figure 5.


static void Main(string[] args)
{
Console.WriteLine("***\r\n Begin program - logging with decorator\r\n");
// IRepository<Customer> customerRepository =
// new Repository<Customer>();
IRepository<Customer> customerRepository =
new LoggerRepository<Customer>(new Repository<Customer>());

var customer = new Customer
{
Id = 1,
Name = "Customer 1",
Address = "Address 1"
};
customerRepository.Add(customer);
customerRepository.Update(customer);
customerRepository.Delete(customer);
Console.WriteLine("\r\nEnd program - logging with decorator\r\n***");
Console.ReadLine();
}

Figure 5 The Main Program Using The Logger Repository


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

public DynamicProxy(T decorated)
: base(typeof(T))
{
_decorated = decorated;
}

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;

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

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

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

Figure 7 The Dynamic Proxy Class


Figure 6 Execution of the Logging Program with a Decorator

Free download pdf