ASP.NET
  Home arrow ASP.NET arrow Page 7 - Demonstrating Attributes and Reflection in...
Dev Articles Forums 
ADO.NET  
Apache  
ASP  
ASP.NET  
C#  
C++  
ColdFusion  
COM/COM+  
Delphi-Kylix  
Design Usability  
Development Cycles  
DHTML  
Embedded Tools  
Flash  
Graphic Design  
HTML  
IIS  
Interviews  
Java  
JavaScript  
MySQL  
Oracle  
Photoshop  
PHP  
Reviews  
Ruby-on-Rails  
SQL  
SQL Server  
Style Sheets  
VB.Net  
Visual Basic  
Web Authoring  
Web Services  
Web Standards  
XML  
Dedicated Servers  
Moblin 
JMSL Numerical Library 
IBM® developerWorks 
Sun Developer Network 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
ASP.NET

Demonstrating Attributes and Reflection in .NET
By: Wrox Team
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 5 stars5 stars5 stars5 stars5 stars / 41
    2003-01-14

    Table of Contents:
  • Demonstrating Attributes and Reflection in .NET
  • What are Attributes?
  • Generic Database Manager
  • Attributes Applied
  • Generating SQL using .NET Reflection
  • Putting it all together
  • Bug Tracking Attribute
  • Conclusion

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
    ADVERTISEMENT


    Demonstrating Attributes and Reflection in .NET - Bug Tracking Attribute


    (Page 7 of 8 )

    Consider the following scenario. You recently released a patch to your latest Wizbang product, and one of your developers "fixed" a bug but introduced four more showstoppers that got past your QA department. Unfortunately the code modifications made to "fix" the bug span multiple assemblies and you don't know where to start.

    What if you could run a utility program that examined the source code and provided a listing of all the affected code related to this bug? Given your programmers have some discipline in using attributes to annotate source code, determining code changes could be accomplished at the click of a button.

    The Issue Attribute

    Let's define a custom .NET attribute that allows developers to identify areas of code affected by a bug fix. Our custom attribute will specify the issue number, name of the programmer, and a description of the change.

    Developers should have the ability to place these attributes on classes, methods, properties, enumerations, etc. Here is the attribute's definition:

    [AttributeUsage(AttributeTargets.All,
    AllowMultiple = true, Inherited = true)]
    Public class BugFixDetails : System.Attribute
    {
    private string _issueID;
    private string _programmerName;
    private string _description;

    public string IssueID
    {
    get
    {
    return _issueID;
    }
    set
    {
    _issueID = value;
    }
    }
    public string ProgrammerName
    {
    get
    {
    return _programmerName;
    }
    set
    {
    _programmerName = value;
    }
    }
    public string Description
    {
    get
    {
    return _description;
    }
    set
    {
    _description = value;
    }
    }

    public BugFixDetails(string ID, string programmer, string desc)
    {
    this.IssueID = ID;
    this.ProgrammerName = programmer;
    this.Description = desc;
    }

    }


    Note that the AttributeUsage attribute allows this attribute to be applied to any of the areas supported by .NET attributes. Here is some sample code containing the BugFixDetails attribute.

    [BugFixDetails("1", "John Q. Programmer",
    "Changed name of class from Test to Test1")]
    public class Test1
    {
    [BugFixDetails("2", "Suzie B. BugFree",
    "Changed _var1 from type object to string")]
    private string _var1;
    private string _var2;

    [BugFixDetails("2", "Suzie B. BugFree",
    "Initialized variables in constructor")]
    public Test1()
    {
    _var1 = "init value 1";
    _var2 = "init value 2";
    }
    [BugFixDetails("3", "John Q. Programmer",
    "Altered code to account for framework exception being thrown")]
    [BugFixDetails("4", "John Q. Programmer",
    "Added in code to rethrow exception being thrown from framework")]
    public void Method1(int a, int b)
    {
    . . .
    }
    . . .
    }


    The Issue Viewer

    Now let's look at a sample application that loads a .NET assembly and searches for all BugFixDetails attributes matching a particular Issue ID. The screen shot below shows the results of a query for Issue ID #1. Note that the source code download contains a sample class library annotated with BugFixDetails attributes.

    Figure 4

    The sample application above opens up the assembly, examines it for BugFixDetails attributes and lists the following:
    • Scope - The element that the code change was applied to (i.e. class, method, enumeration, property, etc).
    • Name - The name of the element (method name, class name, etc).
    • Programmer - The name of the programmer.
    • Description - A description of the bug
    When the user clicks the Find Details for Issue button, the following code is executed:

    private void btnFindIssueDetails_Click(object sender,
    System.EventArgs e)
    {
    try
    {
    // make sure they supplied an issue id
    if(tbIssueID.Text.Trim() == "")
    {
    MessageBox.Show("You must specify an issue ID.");
    return;
    }
    if(tbAssemblyFileName.Text.Trim() == "")
    {
    MessageBox.Show("You must specify the path and " +
    "file name of the assembly to inspect.");
    return;
    }
    // clear all the items in the list
    listView1.Items.Clear();

    // load the assembly so that we can
    // interrogate it
    Assembly assem =
    System.Reflection.Assembly.
    LoadFrom(tbAssemblyFileName.Text);
    // iterate through each type in the assembly
    // we loaded above
    foreach(Type t in assem.GetTypes())
    {
    // add class level issue
    // descriptions for this issue id
    this.AddIssueDetailsForClass(t,
    tbIssueID.Text);
    // add method level issue
    // descriptions for this issue ID
    this.AddIssueDetailsForMethods(t,
    tbIssueID.Text);
    // add property level issue
    // descriptions for this issue ID
    this.AddIssueDetailsForProperties(t,
    tbIssueID.Text);
    // add constructor level issue
    // descriptions for this issue ID
    this.AddIssueDetailsForConstructors(t,
    tbIssueID.Text);
    }
    }
    // catch any exceptions
    catch(Exception ex)
    {
    MessageBox.Show(ex.Message);
    }
    }


    Once the code verifies that the Issue ID and assembly information is entered correctly, it loads the specified assembly and iterates through all of the types.

    Next, the code adds details for bug fixes within classes, methods, properties, and constructors. Let's examine the method that locates custom BugFixDetails attributes at the method level.

    private void AddIssueDetailsForMethods(Type t,
    string issueID)
    {
    // iterate through all the methods of this object
    foreach(MethodInfo mi in t.GetMethods())
    {
    // grab the custom attributes for each method
    foreach(Attribute att in
    mi.GetCustomAttributes(false))
    {
    // cast to our custom attribute
    BugFixDetails dets =
    att as BugFixDetails;

    if(dets != null)
    {
    // do these issue IDs match?
    if(dets.IssueID == issueID)
    {
    // add this issue to the list
    this.AddIssueItemToList("Method",mi.Name,
    dets.ProgrammerName,dets.Description);
    }
    }

    }

    }
    }


    The AddIssueDetailsForMethods first iterates through all of the methods within the type, then through all the custom attributes for each method. After verifying the custom attribute is indeed a BugFixDetails attribute, the method looks at the IssueID of the attribute and, if the Issue IDs match, adds the item to a ListView.

    The code that adds the item to the ListView is listed below:

    private void AddIssueItemToList(string strScope,
    string strName,
    string strProgrammer,
    string strDescription)
    {
    // create the listview item for this issue
    ListViewItem lvi = new ListViewItem(strScope);
    // add all the sub items
    lvi.SubItems.Add(strName);
    lvi.SubItems.Add(strProgrammer);
    lvi.SubItems.Add(strDescription);
    // lets add this to our list.
    listView1.Items.Add(lvi);
    }


    The above code block simply creates a new ListViewItem, populates it with the bug details, and adds the item to the ListView control.

    More ASP.NET Articles
    More By Wrox Team


     

    ASP.NET ARTICLES

    - How Caching Means More Ca-ching, Part 2
    - How Caching Means More Ca-ching, Part 1
    - Reading a Delimited File Using ASP.Net and V...
    - What is .Net and Where is ASP.NET?
    - An Object Driven Interface with .Net
    - Create Your Own Guestbook In ASP.NET
    - HTTP File Download Without User Interaction ...
    - Dynamically Using Methods in ASP.NET
    - Changing the Page Size Interactively in a Da...
    - XML Serialization in ASP.NET
    - Using Objects in ASP.NET: Part 1/2
    - IE Web Controls in VB.NET
    - Class Frameworks in VB .NET
    - Cryptographic Objects in C#: Part 1
    - Sample Chapter: Pure ASP.Net







    © 2003-2008 by Developer Shed. All rights reserved. DS Cluster 3 hosted by Hostway