Skip to content

Object Decoration is Functional Programming

May 1, 2012

Functional Programming (FP) makes easy to add new operations on existing things (types and objects). This can be accomplished by adding new functions which compute with existing types. You can do functional programming in C# using lambda expression.

Object Decoration (OD) attaches behaviors to object. Using OD, you define behaviors as functions and attach them to existing objects. Here is an example to show how it is done using ObjectProxyFactory.CreateProxy of CBO Extender.

doAThing = ObjectProxyFactory.CreateProxy2<IDoAnything>(
    doAThing,
    new string[] { "DoThing" },
    new Decoration2(SayHello, null),
    new Decoration2(SayBye, null)
);

Here, you specify an object doAThing as the first argument, then, its method DoThing, the preprocessing behavior SayHello and the postprocessing behavior SayBye. All it says is that I want to add behavior SayHello before, and behavior SayBye after, the method DoThing of the object doAThing. That call returns a proxy of the original object. Then, you can use the proxy as if it was the original object. Now, the code

doAThing.DoThing();

executes SayHello first, then the actual method DoThing, and last SayBye.

For this example, the SayHello and SayBye are defined as static methods as follows.

public static void SayHello(AspectContext2 ctx, dynamic parameters)
{
    System.Console.WriteLine("Hello!");
}

public static void SayBye(AspectContext2 ctx, dynamic parameters)
{
    System.Console.WriteLine("Bye!");
}

You can also use lambda expressions in place of SayHello and SayBye in the call ObjectProxyFactory.CreateProxy. Here, the call is rewritten using lambda expressions as follows.

doAThing = ObjectProxyFactory.CreateProxy2<IDoAnything>(
    doAThing,
    new string[] { "DoThing" },
    new Decoration2((x, y) => { System.Console.WriteLine("Hello!"); }, null),
    new Decoration2((x, y) => { System.Console.WriteLine("Bye!"); }, null)
);

The complete code is listed as follows.

using CBOExtender;

namespace HelloWorld
{
    public interface IDoAnything {
        void DoThing();
    }

    public class DoAnything : IDoAnything {
        public void DoThing() { }
    }

    class Program
    {
        static void Main(string[] args)
        {
            IDoAnything doAThing = new DoAnything();

            doAThing = ObjectProxyFactory.CreateProxy2<IDoAnything>(
                doAThing,
                new string[] { "DoThing" },
                new Decoration2((x, y) => { System.Console.WriteLine("Hello!"); }, null),
                new Decoration2((x, y) => { System.Console.WriteLine("Bye!"); }, null)
            );

            doAThing.DoThing();
        }
    }
}

As you can see, it is extremely easy to add behaviors to an existing object. All you need to do is provide a function (lambda expresseion).

Using this approach, cross-cutting concerns and special business functionality can be added to existing objects conveniently. Please follow the links for examples of adding various behaviors to objects.

To see how logging, security checking and sorting are added to objects, click here.

To see how transaction is added to objects, click here.

Advertisements

From → CodeProject

14 Comments
  1. jpolvora permalink

    Hello Gary!
    I was looking for something simple to work with dynamic proxies, specially to make things easier in the field of INotifyPropertychanged interface, because I build silverlight/wpf applications.
    Then I found your DynamicDecorator/CBO Extender library and started to do some experiments.
    Finally I made several modifications and refactorings that I would like to share with you. In case you’re interested in, I can send my code with an implementation of INotifyPropertyChanged “behavior” and I will appreciate your thoughts.
    My current implementations works in the following way:
    0 – I created an interface named IAspectBehavior which has methods that the ObjectProxy will call when needed.
    1 – Created a derived IAspectBehavior interface to a class named NotifyBehavior, passing the generic parameter of the interface I want intercept.
    2 – Created an attribute named [AspectAttribute] which I must place on the class I want to apply interception, passing the derived behavior as parameter to the attribute
    3 – Create a new instance of the class that implements the interface of the attribute.
    3 – Created a method on the ObjectProxyFactory class that creates the proxy instance of the class I want. The signature of the method could be simply
    var viewModel = new DynamicProxyViewModel();
    var proxy = ObjectProxyFactory.CreateProxy(viewModel);

    The library takes care of anything, injecting and executing the aspect from attribute to IAspectBehavior.
    I believe in some cases, delegates and lambdas inside a class can be lead to repetitive code…

    • jpolvora permalink

      Here is the github gist of the code, all in one class.

      • Hi jpolvora,

        Thanks for sharing. Will definitely check it later.

        For your information, I do have an article to discuss DynamicDecorator for WPF (http://www.codeproject.com/Articles/270347/Configurable-Aspects-for-WPF-Application-Using-AOP). The issue with INotifyPropertyChanged is that the WPF doesn’t take proxies for binding. So I had to use the Proxy Pattern to work around.

        It will be interesting to see how you address this!

      • BTW, I noticed your code still using older version of DynamicDecorator. There is a newer version CBO Extender 1.2 (http://centurytechs.com/CBOExtender.html). You can also search CBOExtender in Visual Studio from NuGet.

        The CBO Extender 1.2. uses dynamic type instead of object type. So it is more flexible to add behaviors at runtime. No need for generics, too.

        Please let me know if you have problem to get the newer version.

      • jpolvora,

        A few more questions. Do you have examples to show how to use your code? I am particularly interested in how to address the INotifyPropertyChanged.

        And in your first comment, there is code

        var viewModel = new DynamicProxyViewModel();
        var proxy = ObjectProxyFactory.CreateProxy(viewModel);

        But, I cannot find ObjectProxyFactory.CreateProxy in https://gist.github.com/2716022.

  2. jpolvora permalink

    Just updated ! https://gist.github.com/2716022

    I downloaded from an article of codeproject, then I discover that exists the 1.2 version, which my code is based. (To avoid this confusion by other people, I suggest you upload the entire solution as an open source project in some specialized site, like github or codeplex).

    Actually I’m focused on the DynamicProxy project from the solution, I have customized your code, now I’m working on samples.

    At this moment I can do something like this:

    I’m finalizing my work around for INotifyPropertyChanged, can’t wait to share with you.

  3. jpolvora permalink

    Implementations for INotifyPropertyChanged

    #1 https://gist.github.com/2728270 => POCO must implement INotifyPropertyChanged

    #2 https://gist.github.com/2728325 => POCO must implement INotifyPropertyChangedExtended

  4. jpolvora permalink

    Since WPF can bind to DynamicObjects, the best solution I found is wrap an object in a derived custom DynamicObject class, using the same approach of RealProxy.

    But I like the approach with real proxy, since we can intercept .NET framework classes.

    I’ve discovered a nice framework to cast any object to any interface, it’s called Impromptu-Interface.

    Take a look at http://code.google.com/p/impromptu-interface/

    For example, we can create an interface with any method that a .net class implements. Then, we cast that object to this interface and create a proxy with DynamicProxy, wrapping that object, and intercept with our aspects.

  5. jpolvora permalink

    Awesome solution ! Proxy + DuckTyping with Impromptu-Interface

    • What a great idea! Impromtu-Interface + Dynamic Decorator is a saver for OOP!

      Thanks for sharing,

    • Hi jpolvora,

      I found a little lost while trying to follow you code. It looks like there are a few jumps. What is the differences between ObjectProxyFactory.CreateUsingAttribute and ObjectProxyFactory.CreateUsingActions? What are the advantages of them?

      I encourage you to write a codeproject article (or other article) if you think you have solved an interesting problem like proxy and WPF’s INotifyPropertyChanged with complete working examples. It helps organizing your ideas and helps readers to understand.

      BTW, I just published an article “Object Decoration With Impromptu-Interface”
      (http://www.codeproject.com/Articles/393710/Object-Decoration-With-Impromptu-Interface) and mentioned your recommendation of Impromptu-Interface.

      Thanks,

      Gary

  6. Thanks for the mention. Today I read your new post on CodeProject and downloaded the solution and started to convert/adapt your example to my implementation of DynamicProxy/DynamicDecorator, so now you can easilly follow my code, by comparing both solutions side-by-side.

    I’ve made a few comments on code and I believe everything else is self-explained.

    Since the first comment on this blog post, I’ve started to mess the design of Object Decoration, as you could see in the gist codes that were linked in the previous comments, but now I’ve made several refactorings and optimizations, turning it simpler and powerful than before. I removed all that boilerplate attributes and interfaces and cleaned the code. My code initially followed yours, but the result now have some functionalities that I guess will like.

    Some differences:

    * I removed the delegate types that was used as pointers to the pre/post aspects. I switched to use Actions.

    * I didn’t see a good reason to maint the class Decoration only for store data, so I removed them. Most of logic was moved to ObjectProxy class, including the List of Actions that perform pre/post decorations.

    * I don’t like “magic strings”, so I’ve created some helper methods that provide the method names that will be intecepted, in a strongly typed way, using Expression<Action>.

    * I’ve created a FluentBuilder class to Configure the pre/post aspects and parameters. You will see in the example attached.

    * I’ve integrated the ImpromptuInterface as a dependency, the programmer don’t need to call ActLike every time when passing the target object to the ObjectProxyFactory. The ObjectProxyFactory will determine automatically if the target object needs to be “duck typed” before creates the proxy and will call ActLike if necessary. This is all done transparently to the client user.

    * The most notable difference I will explain now is that with my current implementation, you can chain several Pre/Post actions with the fluent builder, so there’s no more need to proxy the proxied subproxied instances for just adding new aspects. All aspects will be added to a list of Actions and they are executed in the order they’re added to the list.

    The file can be downloaded at http://dl.dropbox.com/u/14150556/OdWithImpromptuI.rar

    I expect you appreciate and feel free to copy/modify or integrate in CBO Extender.

    • Hi Jone,

      I like the ideas of integrationg impromptu-interface with ObjectProxy, Expression for methods, fluent buider for configuring ObjectProxy.

      A question for SetParameters. Since multiple parameters can be passed in, it is not clear which parameter goes to which aspect if all parameters are in one list. It will be clearer if the code can be like this.

      var proxiedOrderDetail = ObjectProxyFactory.Configure(orderDetail)
      .FilterMethods(oDet => oDet.InsertOrderDetail())
      .AddPreDecoration(AppConcerns.SecurityCheck, Thread.CurrentPrincipal)
      .AddPreDecoration(AppConcerns.JoinSqlTransaction, transactionObj)
      .AddPreDecoration(AppConcerns.EnterLog)
      .AddPostDecoration(AppConcerns.ExitLog)
      .CreateProxy();

      Basically, I want to transaction object goes to JoinSqlTransaction only and Thread.CurrentPrincipal goes to SecurityCheck only.

      I’ll try integrate your ideas into CBO Extender when I get chance. By the way, I think you have pretty good understanding of my original ideas of dynamic decorator. I encourage you to publish your work to the community so more people can be benefited from your work.

      Thanks,

      Gary

  7. Hi again Gary, the point in setting parameters the way I’m doing is to share the parameter values between the pre and post decorations. Imagine a situation when I need to check some value in the pre decoration, and depending on a business logic, I want to pass a parameter that will be used in the post decoration to do another business logic. This idea I have when I was trying to implement some logic to solve the notifypropertychanged behavior. Another important feature in the predecoration is that sometimes depending on my logic in the predecoration, I could cancel the execution of a postdecoration, for example. Then I create an property of type boolean “Abort” in the AspectContext (ctx) instance passed to the decorations. The executor of the aspects, at the ObjectProxy class, will check if abort is true and then will not execute the subsequent aspects/decorations.

    Thanks for your patience.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: