|
CodeProjectThe Generic Dynamic Decorator enhances the Dynamic Decorator to be strongly typed by using .NET Generics.
As you may be already aware of, when creating proxy using ObjectProxyFactory.CreateProxy you need to cast it to a specific interface type, whose methods you want to attach extra behaviors to. The issue is that if it is cast to a wrong type of interface, the code passes the compilation and even executes until you use it to call a method. Then, it generates a runtime error.
With the Generic Dyanmic Decorator, the ObjectProxyFactory.CreateProxy<T> returns a strongly-typed interface. There is no need to do the dynamic cast any more. If a wrong type of interface is specified, the code may pass the compilation but will generate a runtime error during the creation of the proxy before you get a chance to use the interface to call a method.
The following code demonstrates how to use the Generic Dynamic Decorator to add entering log to the method DetailsByLevel of the object emp of the class Employee .
static void Main(string[] args)
{
IEmployee emp = new Employee(1, "John", "Smith", new DateTime(1990, 4, 1), 1);
System.Int32? id = null;
System.String detail = "";
emp = ObjectProxyFactory.CreateProxy<IEmployee>(
emp,
new String[] { "DetailsByLevel" },
new Decoration((x, y) =>
{
IMethodCallMessage method = x.CallCtx;
string str = "Calling " + x.Target.GetType().ToString() + "." + method.MethodName +
"(";
int i = 0;
foreach (object o in method.Args)
{
if (i > 0)
str = str + ", ";
str = str + o.ToString();
}
str = str + ")";
Console.WriteLine(str);
Console.Out.Flush();
}, null),
null);
id = emp.DepartmentID;
detail = emp.DetailsByLevel(2);
}
More information about extending functionality of an object using Dynamic Decorator can be found in the article Dynamic Decorator Pattern.
For examples and features which can be used to write powerful aspects for objects, please refer to the article Add Aspects to Object Using Dynamic Decorator.
For principles how to use the Dynamic Decorator in your application development in general, please refer to the article Components, Aspects, and Dynamic Decorator.
For using Dynamic Decorator in ASP.NET application, please refer to the article Components, Aspects and Dynamic Decorator for ASP.NET Application.
For using Dynamic Decorator in ASP.NET MVC application, please refer to the article Components, Aspects, and Dynamic Decorator for ASP.NET MVC Applications.
For using Dynamic Decorator in Silverlight/WCF application, please refer to the article Components, Aspects, and Dynamic Decorator for Silverlight / WCF Service Applications.
For using Dynamic Decorator in MVC/AJAX/REST application, please refer to the article Components, Aspects and Dynamic Decorator for MVC/AJAX/REST Application.
modified on Thursday, July 21, 2011 12:16 PM
|
|
|
|
|
People seem interested in the Dynamic Decorator but concern about the performance overhead of the .NET remoting. Here, I try to clarify some mystery of the implementation of Dynamic Decorator.
First, the Dynamic Decorator does not use the runtime implementation of RealProxy. Instead, it implements its own RealProxy - ObjectProxy. Therefore, the performance overhead related to the runtime implementation of RealProxy does not apply to the ObjectProxy.
Second, let's dig into the code of the ObjectProxy to see whether the performance is a concern. In Dynamic Decorator, a transparent proxy of the target object is returned by ObjectProxyFactory.CreateProxy method. The proxy is registered by the runtime so that when it is used to call a method, the runtime intercepts the call. This mechanism allows you to add preprocessing or postprocessing functionality before or after the target method invocation by overriding the Invoke method of the RealProxy.
If you step into the code, you will see the proxy call is resolved to a call of RealProxy.PrivateInvoke. The RealProxy.PrivateInvoke calls the virtual method RealProxy.Invoke, which is overridden by the ObjectProxy.
So, the actual work is done inside the overridden Invoke method. Inside the Invoke method of ObjectProxy, the preprocessing code is executed, then, the target method, finally, the postprocessing code.
People get impression that remoting is costly due to the runtime implementation of the RealProxy, or more specifically, the runtime implementation of Invoke method. However, that is not the case for ObjectProxy. As you see in the code of Invoke of ObjectProxy, there is no costly operations like crossing app domains, crossing contexts or context switch. It is simple code for preprocessing, target method invocation and postprocessing. They are all juicy stuff not overhead.
The other area of performance overhead is the intercept mechanism itself. It is a bit blackbox how the intercept mechanism is implemented. However, the logic behind is straightforward: if it is a transparent proxy object, call the Invoke method of its RealProxy. I cannot think of any costly operations in this.
In the end, the implementation of the Dynamic Decorator is very light and thin.
modified on Monday, April 18, 2011 7:27 AM
|
|
|
|
|
CodeProjectIt is clear that aspects address system (non-functional) requirements while classes address business (functional) requirements. System requirements are runtime requirements when software executes and are best addressed at object level .
Unfortunately, for all these years most of the AOP products/tools try to address aspects at class level at its design time. That may explain why AOP is still not widely adopted. In my opinion, classes should only concern about business requirements. They should not concern about system requirements. System requirements should be addressed at object level when you use the objects of the classes.
Here is why. A class is only a template for a set of objects. When you design a class, often you do not know (or may never know) every situation in which its objects are used. Take the logging (a system requirement, BTW) as an example. If you add the entering/exiting logging aspects to a class method, every object created from the class will pump entering/exiting logs when executing the method. If your code just loop through a few employees, it is probably ok. If you have hundreds of thousands of employees, do you really want to log every entering/exiting in the loop? You just can't anticipate the situations like this.
My point here is: it is too early to decide whether you need an aspect to your class when you design the class. Then, when is the right time to consider an aspect? The answer is when you use objects of the class. By the time you use an object of the class in your code, you know the exact situation in which the object is used. Then, you can decide whether an aspect is needed for the object. If yes, the Dynamic Decorator (or maybe other tools) can be used to attach aspects to the object at the spot.
Using the Dynamic Decorator, business requirements and system requirements can be addressed separately. You use OOP to design classes to satisfy the business requirements. Then, you use the Dynamic Decorator to attach aspects to objects as needed based on the system's runtime requirements.
I agree that Dino Esposito's comment in his article Aspect-Oriented Programming, Interception and Unity 2.0 while he describes the benefits of AOP: the main reason for such a limited adoption (of AOP) is essentially the lack of proper tools. More specifically, I would like to say that although there exist a number of AOP tools, it is still lack of tools to address aspects at right time and at right place.
The Dynamic Decorator may be one of first serious tools to address aspects at object level. I foresee more tools will come to address aspects at object level in the near future for two reasons. First, the needs are there. Second, people may shift their focus onto solving the AOP problem at object level once they realize that aspects belong to objects at runtime not classes at design time.
More information on aspects to object can be found in the article Add Aspects to Object Using Dynamic Decorator.
modified on Wednesday, July 13, 2011 1:15 PM
|
|
|
|
|
Using the GoF Decorator Pattern, you can add additional functionality to a particular object without subclassing its class. However, you do need to create decorator class or classes at source code level. For each type of object, you need an abstract base decorator class, one or more concrete decorator classes. Imagine that you apply the Decorator Pattern to several of different types of objects. You will end up to have a lot of decorator classes. That may result in tremendous maintenance efforts when requrirements evolve. It may involve modifying, compiling, testing, deploying and supporting these decorator classes.
The Dynmaic Decorator Pattern solves the same problem as the GoF Decorator Pattern without the need of source code level decorator classes: add additional functionality to a particular object at runtime without subclassing. It achieves this by taking a different route: it uses .NET proxy technology to intercept method calls and attach the additional functionality along the way dynamically at runtime.
The Dynamic Decorator can be used to add extra functionality to any types of objects and treats them in the same way. The types can be your custom types, .NET Framework types, or third party types. Actually, it is type-oblivious. It can be cast to any type. It resolves to a specific type when it is used to make a method call at runtime.
The Dynamic Decorator is a general purpose solution for adding extra functionality to object at runtime. It is not limited to some particular types.
|
|
|
|
|
By far, quite a few discussions on AOP using .NET Framework are based on ContextBoundObject. To add some aspects to your class, it has to meet the following prerequisites:
1. The class needs to have ContextBoundObject as its base class;
2. All method calls need to cross object context;
3. An aspect applies to all methods of the class.
Most of business objects cannot afford to meet these prerequisites. So you really cannot do serious AOP development based on ContextBoundObject.
Using Dynamic Decorator, aspects can be added to your class without the above prerequisites. To be specific:
1. Your class doesn't have to have a base class;
2. Method calls do not cross object context;
3. An aspect applies to methods at your choices.
Dynamic Decorator is a flexible, lightweight solution to add extra functionaliy to objects.
modified on Thursday, October 7, 2010 11:59 PM
|
|
|
|
|
About five years ago, I got to know dynamic proxy concept and tried some Aspect Oriented programming. At first, I was excited about the AOP since it declares to address crosscutting concerns that cannot be solved by OOP effectively. Before long, I realized that AOP was a heavyweight approach to address some of my existing issues and I didn't know whether it would cause more issues than it addressed.
Some articles discussed AOP using existing .NET remoting infrastructure. They all had a serious limitation in that only classes derived from ContextBoundObject could have aspects added. That really didn't take me too far. I concluded that the AOP for .NET was too early. Then, I moved on until recently I got chance to go over one of my favorite books - "Agile Principles, Patterns, and Practices in C#" (Robert C. Martin).
The way the author describes patterns made me thinking. While going through the sections of Decorator pattern in the book, I kept thinking that it must have taken some really smart guys to figure out this pattern. But what I really wanted was to add some extra functionality to my object. I don't want to go through all decoration class design exercises every time I need some additional functionality to an object.
That made me think about the dynamic proxy again. I thought that maybe I could do something with the dynamic proxy to add extra functionality to an object without changing the source code. That led the idea of Dynamic Decorator pattern.
In the next blog, I'll discuss how the Dynamic Decorator overcomes the shortcomings associated with the dynamic proxy that uses existing .NET remoting infrastructure.
modified on Monday, February 14, 2011 10:49 PM
|
|
|
|
|
I couldn't fall asleep on Sep. 29th late night. So I decided to publish the "Add Aspects to Object Using Dynamic Decorator". The publishing was smooth and by the time of its completion it must have way passed Sep. 29th and into Sep. 30th's morning.
Two days ago, I googled (or binged) the above title. To my surprise, an England guy Chris Alcock had commented the article on Sep. 30th at 08:49AM. Considering the time difference between England and US East, he must have seen the article immediately right after I published it, read it and gone through the code and examples, and made the comments.
I excerpt his comments here(see link):
"Gary H Guo looks at creating Aspect Oriented Programming functionality to add behaviours to business entities to implement functionality like security. The implementation here is a thin (and understandable) layer over the built in .NET Proxy functionality, and looks like a nice example of AOP principles and implementation".
I am impressed not only his precise comments but also the unprecedent speed for the article to reach to its readers.
In my next blog, I am going to tell a little history of the Dynamic Decorator.
|
|
|
|
|
Hi, there!
This is a test.
|
|
|
|
|