Click here to Skip to main content
Click here to Skip to main content

Dynamic Type With Component-Based Object Extender

, 1 Dec 2011 CPOL
Rate this:
Please Sign up or sign in to vote.
Introducing dynamic type to Component-Based Object Extender.

Introduction

Component-Based Object Extender (CBO Extender) is an object extensibility framework. It is a general-purpose tool for adding functionality to objects by attaching behaviors to interface methods of the objects at runtime.

The dynamic type of .NET 4 simplifies the definition of behaviors and makes programming with CBO Extender more flexible. In this article, I discuss how the dynamic type in C# is used to define behaviors and add them to objects with CBO Extender.

Background

CBO Extender adds functionality to objects at runtime without involving design changes of components. With CBO Extender, you define a set of aspect methods to represent behaviors based on your business or system requirements. Then, you can attach the methods to objects as needed in your application. The application development and maintenance are made easier by putting concerns into individual methods and applying them to objects at runtime. There are several articles that discuss how to add functionality like logging, security checking, sorting, and transaction management to applications using CBO Extender. Please see Application Development With Component-Based Object Extender and Transaction Management With Component-Based Object Extender for details.

.NET 4 supports the dynamic type, which enables operations to bypass compile-time type checking and be resolved at runtime. Since CBO Extender is a runtime tool for object extensibility, using the dynamic type can significantly simplify programming and make aspect methods much more flexible and powerful.

CBOExtender 1.2 introduces the dynamic type into aspect methods and can be downloaded as a NuGet package. You can also download the source code, latest updates, and more examples at http://centurytechs.com/CBOExtender.html.

To install CBOExtender to your project from Visual Studio 2010, click Tools->Library Package Manager->Manage NuGet Packages... to open the Manage NuGet Packages dialog. Type in CBOExtender as shown.

You probably need to install NuGet for Visual Studio 2010 before you can download the package.

The following discussions assume that you have read the above articles by following the links and have a basic understanding of what problems the CBO Extender tries to solve and how to solve them.

Use the Code

In the following sections, I discuss how to define an aspect method with the dynamic type. Then, I present two different approaches for attaching the aspect to an object. The two approaches are: using CreateProxy2 and using ChainAspect2. Most of the code is from the example application in the download.

Define Aspect

First and foremost, the dynamic type makes the definition of an aspect method significantly simpler. The following example defines an aspect method for adding a command to a transaction without using the dynamic type.

public static void JoinSqlTransaction(AspectContext ctx, object[] parameters)
{
    try
    {
        if (parameters != null && parameters[0] is IDbTransaction)
        {
            (ctx.Target as ISqlOperation).Command.Transaction = 
                        parameters[0] as SqlTransaction;
            return;
        }
    }
    catch (Exception ex)
    {
        throw new Exception("Failed to join transaction!", ex);
    }
}

With the dynamic type, the aspect method is rewritten as follows. Both parameter and Target are dynamic types.

public static void JoinSqlTransaction(AspectContext2 ctx, dynamic parameter)
{
    try
    {
        ctx.Target.Command.Transaction = parameter;
        return;
    }
    catch (Exception ex)
    {
        throw new Exception("Failed to join transaction!", ex);
    }
}

As you see, runtime type checking code is no longer needed. The types are resolved at runtime when the method is called in your application. The difference between AspectContext2 and AspectContext is that the AspectContext2 has a Target of dynamic type while AspectContext has a Target of object type.

Furthermore, the method with dynamic type is not limited to parameter as SqlTransaction, and Target as ISqlOperation. Any type of object can be passed to parameter and Target can reference to any type of object as long as the implementation of the types makes the statement ctx.Target.Command.Transaction = parameter; work when it is executed. For example, you may call this method somewhere in your application by passing an OracleTransaction object to parameter with Target as IOracleOperation presuming that you have defined OracleTransaction and IOracleOperation and implemented the Target's type properly so that the runtime can resolve the types and execute the statement ctx.Target.Command.Transaction = parameter;.

The corresponding delegate for the aspect method with the dynamic type is DecorationDelegate2, which is defined as follows:

public delegate void DecorationDelegate2(AspectContext2 ctx, dynamic dynPara);
public class AspectContext2
{
    /// dynamic type Target
    public dynamic Target { get; set; }

    /// 
    public IMethodCallMessage CallCtx { get; set; }

    /// 
    public AspectContext2(object target, IMethodCallMessage callCtx)
    {
        Target = target;
        CallCtx = callCtx;
    }
}

Any method with the signature defined by the delegate can be encapsulated in an instance of the delegate.

Use CreateProxy2

The CreateProxy2 method of the ObjectProxyFactory class can be used to associate aspects to an object and has the following signature:

public static T CreateProxy2<T>(object target, 
        String[] arrMethods, Decoration2 preAspect, Decoration2 postAspect)

Decoration2 encapsulates a DecorationDelegate2 object and a dynamic object, and has a constructor with the following signature:

public Decoration2(DecorationDelegate2 aspectHandler, dynamic parameter)

The following code shows how CreateProxy2 is used to add the join transaction aspect to an object o.

ObjectProxyFactory.CreateProxy2<IOrder>(
    o,
    new string[] { "InsertOrder" },
    new Decoration2(AppConcerns.JoinSqlTransaction, transaction),
    null
)

o is the target object whose type should implement the interface IOrder. The target type should also implement an interface ISqlOperation to ensure that the JoinSqlTransaction does not throw an exception at runtime. The second argument indicates only the method InsertOrder of the target should be decorated with the aspects specified in the rest of the arguments (preAspect - the preprocessing decoration, postAspect - the postprocessing decoration). The preprocessing decoration consists of a delegate object for the JoinSqlTransaction method and a dynamic type object transaction. No postprocessing decoration is specified for this case.

Basically, the above code lays down the logic that adds the command associated with the target to the transaction at runtime prior to calling the InsertOrder method of the objet o.

Use ChainAspect2

If you use some kind of IoC container, you probably want to use the ChainAspect2 method of AOPContainer to associate aspects to an object. ChainAspect2 has the following signature:

public static V ChainAspect2<T, V>(T target, string methods, 
              Decoration2 preDeco, Decoration2 postDeco) where T : V

The following code shows how ChainAspect2 is used to add the join transaction aspect to an object o.

AOPContainer.ChainAspect2<IOrder, IOrder>(
    o,
    "InsertOrder",
    new Decoration2(AppConcerns.JoinSqlTransaction, transaction),
    null
)

Conclusion

In addition to the benefits of CBO Extender presented in the article Component-Based Object Extender, the CBO Extender combined with the dynamic type makes object extending much easier and more flexible.

Note: This article only shows how the dynamic type is used to define aspects and how the aspects are added to objects. You may need to download the source code to understand how they fit in the context of an application. The source code rewrites the example in the article Transaction Management With Component-Based Object Extender using the dynamic type.

License

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

Share

About the Author

Gary H Guo

United States United States
Object-oriented (OO) is about "classes" not "objects". But I truly believe that "objects" deserve more our attentions. If you agree, read more on... Dynamic Object Programming (DOP), Component-Based Object Extender (CBO Extender), AOP Container and Dynamic Decorator Pattern.
 
Mobile development is not just another type of front end. The real challenge is actually in the back end: How to present meaningful information in time to mobile users with exponentially increased data flooding around? Here is my first mobile solution: SmartBars - Barcode Reader, Price Comparison and Coupons.
 
Gary lives in southeast Michigan. My first programming language is FORTRAN. For the last a few years, I have primarily focused on .NET technologies with Mobile Development as my newest interest.

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.1411023.1 | Last Updated 1 Dec 2011
Article Copyright 2011 by Gary H Guo
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid