Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Object Decoration is Functional Programming

5.00/5 (2 votes)
3 May 2012CPOL1 min read 7K  
Discuss object decoration, functional programming and dynamic behaviors

Functional Programming (FP) makes it 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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)