A great feature of .NET is the ability to mark your code with declarative attributes. These can be used for a variety of purposes, such as how objects should be mapped to database tables, and for marking code to use with framework tools. This approach leverages the benefits of declarative programming and the applications for this are limitless.The demo below is a simple scenario where a custom attribute is created that allows a developer to mark code as not being fully implemented. This could then be used with testing or QA frameworks to analyse the code. In our case we will just scan the class using reflection and prints out a message indicating whether the code is considered fully implemented or not.

The first thing that we must do is to define our attribute:

using System;
using System.Text;
 
namespace DemoAttribute
{
    public class NotFullyImplementedAttribute : Attribute
    {
        public override string ToString()
        {
            return "indicate that a member must be implemented.";
        }
    }
}

Here the ToString() method prints out a message for the NotFullyImplemented status. We can now use this attribute to decorate members of our classes as shown below:

using System;
using System.Text;
namespace DemoAttribute
{
    class Employee
    {
        private string _name;
        public Employee()
        {
        }
        
        public string Name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
            }
        }
        [NotFullyImplementedAttribute()]
        public void PayEmployee()
        {
            // To Do
        }
    }
}

In this case we are using our custom attribute to decorate the PayEmployee() method of the Employee class so that we can indicate that this method is not fully implemented.  An example of how this attribute can be then interpreted is shown below, where we use reflection to examine the methods of the class Employee.

using System;
using System.Reflection;
using System.Text;
namespace DemoAttribute
{
    class MainApp
    {
        private static bool IsFullyImplemented(MemberInfo member)
        {
            foreach (object attribute in member.GetCustomAttributes(true))
            {
                if (attribute is NotFullyImplementedAttribute)
                {
                    Console.WriteLine(attribute.GetType().ToString()+ 
                        ": This attribute is to "+attribute.ToString  ());
                    return true;
                }
            }
            return false;
        }
 
        public static void Main()
        {
            foreach (MethodInfo method in (typeof(Employee)).GetMethods())
            {
                if (IsFullyImplemented(method))
                {

Console.WriteLine

("Method {0} is not fully implemented.", method.Name);

                }
                else
                {

Console.WriteLine

("Member {0} is implemented!", method.Name);

                }
            }
            Console.Read();
        }
    }
}

We use the GetMethods() routine to get a collection of the methods in the type Employee. We iterate through this collection and call the IsFullyImpemented function, which tests the attributes of each method (a method can have more than one attribute to see if it is decorate with the NotFullyImplemented attribute.

Download Solution - DemoAttribute.zip


Posted by: pwalsh
Posted on: 4/20/2009 at 1:35 PM
Tags:
Categories: Reflection
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed
 
 

 

It is possible to load an assembly at run time, create an instance of a type and invoke a method. In this example I will load the assembly that contains the System.Math namespace and invoke a method for square root. This is a simple example and would make more sense if the assembly was developed by a third party. Doing the binding and invocation at run time is extremely use in cases where you do not want to tightly couple the code by compiling in a fixed assembly. Also in the example below we have explicitly specified the "Sqrt" method. It would be more realistic to use reflection to search the assembly for the method at run time. Another way of exploiting this would be to provide a configuration file that specifies both the name of the assembly and the method. In this way we have significantly decoupled the application code from the third party code.

using System;
using System.Text;
using System.Reflection;
 
namespace LateBindingInvokeFrom_Type
{
    class Program
    {        
        static void Main(string[] args)
        {
            Assembly a = Assembly.Load("mscorlib");
            Console.WriteLine(a.FullName);
            Type mType = a.GetType("System.Math");                        
            object ob = mType.InvokeMember("Sqrt", 
                    BindingFlags.InvokeMethod | BindingFlags.Static | 
                    BindingFlags.Public, null, null, new object[] { 3.14 });
            Console.WriteLine("Object to string {0}", ob.ToString());
            double dblValue = (double)ob;
            Console.WriteLine("Type cast object to double to string {0}",
                  dblValue.ToString());
            Console.Read();
        }
    }
}
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
 

Download Solution - LateBindingInvokeFrom Type.zip


Posted by: pwalsh
Posted on: 4/18/2009 at 6:02 AM
Tags:
Categories: Reflection
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed