Archive for category Reflection

C#: Reflect and Load Entities From a DataSet using a Generic Method and Attributed Entities

iStock_000011856107XSmall If one is not using Linq-To-Sql and the entities are not being generated and loaded, one has to create their own entities and manually load the data into the it. Sure the process for doing one or two entities is ok when done by hand; but it becomes very repetitive grunt work for two or more. This article shows how to decorate an entity with attributes and then using reflection in a generic method load the data from a dataset in C#. This can be done with any version of .Net from 3.5 or greater.

Entity

To make this magic happen we need to decorate our entity with a C# attribute which describes the target column name in the database. Thanks to the System.Xml.Serialization namespace we can use the XmlElement attribute. It has an attribute within itself the ElementName attribute which is an excellent vehicle for what we need to do.

In the class below we have two strings, a DateTime and a decimal. Using the XmlElement we define what all of the target database column names are for each individual mapping of the property to hold the data.

public class Site
{

    [XmlElement(ElementName = "ID")]
    public decimal ID { get; set; }

    [XmlElement(ElementName = "Site_Code")]
    public string Code { get; set; }

    [XmlElement(ElementName="Site_Description")]
    public string Description { get; set; }

    [XmlElement(ElementName = "REQ_PROP_ORIG")]
    public DateTime? Origination { get; set; }

}
Using

Here are the usings if you don’t want to do <CTRL><.> on each error in the file to resolve the namespace for the next sections code.

using System.Reflection;
using System.Xml.Serialization;
using System.ComponentModel;
using System.Globalization;
Generic Method and Reflection

Here is the generic method in a static class. In the next section I describe what is going on when this class is called with a data row and the target entity instance is returned. (See the section Example Usage below to see it in action.)

public static class EntityHelper
{

    public static TEntity CreateEntityFromDataRow<TEntity>(DataRow drData)
        where TEntity : class, new()
    {

        Attribute aTargetAttribute;
        Type tColumnDataType;

        TEntity targetClass = new TEntity();

        Type targetType = targetClass.GetType(); // The target object's type

        PropertyInfo[] properties = targetType.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);

        // Enumerate the properties and each property which has the XmlElementAttribute defined match the column name
        // and set the new objects value..
        foreach (PropertyInfo piTargetProperty in properties)
        {
            aTargetAttribute = Attribute.GetCustomAttribute(piTargetProperty, typeof(XmlElementAttribute));

            if (aTargetAttribute != null)
            {
                try
                {
                    foreach (DataColumn column in drData.Table.Columns)
                    {

                        if (((XmlElementAttribute)aTargetAttribute).ElementName.ToUpper() == column.ColumnName.ToUpper())
                        {

                            if (drData[column.ToString()] != DBNull.Value) // Only pull over actual values
                            {
                                tColumnDataType = drData[column.ToString()].GetType();

                                // Is the data in the database  a string format and do we
                                // want a DateTime? Do the below checks and if so covert to datetime.
                                if ((tColumnDataType != null) &&
                                    (tColumnDataType == typeof(System.String)) &&
                                    (piTargetProperty.PropertyType.IsGenericType) &&
                                    (piTargetProperty.PropertyType.GetGenericTypeDefinition().Equals(typeof(Nullable<>))) &&
                                    ((new NullableConverter(piTargetProperty.PropertyType)).UnderlyingType == typeof(System.DateTime)))
                                {
                                    // The below pattern dd-MMM-YY is for an Oracle date target. You may need to change this depending
                                    // on the database being used.
                                    DateTime dt = DateTime.ParseExact(drData[column.ToString()].ToString(), "dd-MMM-YY", CultureInfo.CurrentCulture);
                                    piTargetProperty.SetValue(targetClass, dt, null);
                                }
                                else // Set the value which matches the property type.
                                    piTargetProperty.SetValue(targetClass, drData[column.ToString()], null);
                            }
                            break; // Column name and data associated, no need to look at the rest of the columns.
                        }
                    }
                }
                catch (Exception ex)
                {
                    throw new ApplicationException(string.Format("Load Failure of the Attribute ({0}) for {1}. Exception:{2}",
                        ((XmlElementAttribute)aTargetAttribute).ElementName, targetType.Name, ex.Message));
                }
            }
        }

        return targetClass;
    }
}
Explanation
  • Line 4: The generic method is defined to accept a generic type definition (the entity we are working with) but accept a DataRow as the actual data and return the generic type as a valid instance.
  • Line 5: This line requires that the generic type is a class and can be new’ed up. New because we will creating new entity instance at run time. See line 10.
  • Line 11: Simply new up a new entity to return.
  • Line 13/15: We begin to examine the generic type which will lead to the discovery of the properties we are looking at. Note we want all properties regardless of their access level. You can specify just public or private by removing the flags setup on line 14. (For more on this see my blog article .Net Reflection 101: Accessing The String Properties of an Active Object).
  • Line 19: We will enumerate upon the reflected properties of the type and match by reflected Element Name to Column Name.
  • Line 21: Here we reflect and get the custom attributes of the type for usage later.
  • Line 27: Now we begin to find the associated column by enumerating over each column found in the row.
  • Line 30: Does the reflected name match the current column name?
  • Line 35: What is the reported data type from the current row column? This is usede in the if of 39-43.
  • Line 39-43: Some databases return a string value for specific dates/times. If that is the case and we are looking at a string held date value do specialized processing to extract the date/time. If your database returns a DateTime object you can remove this if check.
  • Line 51: Assign the data in the column to the instances property via reflection in SetValue.
Example Usage
List<Site> SiteList = new List<Site>();

DataSet ds = new DataSet();

{Data Adaptor}.Fill( ds ); // Fill the dataset from a data adapter. 

// Convert the data in the dataset into a list of the target types.
foreach (DataRow dr in ds.Tables[0].Rows)
    SiteList.Add(EntityHelper.CreateEntityFromDataRow<Site>(dr));
Share

Tags: ,

Linq in C# Learn to Return IEnumerable and not List<>

(Updated 3/27/2011 and works with .Net 3-4)

When I wrote this article I was fixated on returning IEnumerable instead of of List<>. Being a wiser developer my advice now would be to return IList<> instead of IEnumerable in most situations after using the extension ToList() to not have any differed execution due to IQueryable. One should return IList<> because List<> is malleable and can be changed by the consumer in some situations which may have undesired effects elsewhere. My intent now with this article is just to understand how IQueryable uses IEnumerable, such as does List<> and really when to use IQueryable and how it may effect the code.. To that end I have reworked this article.

IQueryable and IEnumerable and List<>

In .Net 2.0 with the release of generic collections one would return List<> and was not too concerned with IEnumerable which List<> derives from. This changed with .Net 3 and the iQueryable returns.

With Entity Framework and Linq to Object/SQL the ability to build queries (differed execution) was presented to the user. A querable item means that the operation in question is held off until the data values are actually needed. The IEnumerable which List<> and IQueryable inherits from simply provides the common base for operations for items to be enumerated (listed).

Stating again, when one uses or returns IQueryable, the operation of getting the list is not done until the data is actually needed; it is differed.  (One can see that in the Visual Studio debugger when viewing the querable list in question, one has to click on it to enumerate it in the debugger before values are shown! When data is not IQuerable the debugger can show it immediately.)

Whereas wiht List and other IEnumerable derived lists,  such as IList<>, the process is done immediately (unless the parent object is IQueryable then one needs to covert it to a hard List<>). Differed operations are good when building a larger set of data outside the method returing IQueryable. But it is not always needed.

Since the execution is differed changes in the list will be reflected at the time of acquisition. Meaning that if you know the list may change and the user should not see those changes, send back a list and not a Queryable. That is done by calling ToList with any Linq operation.

Original Article

When you find a pattern in programming that is a sign that you need to place it into a function for reuse. With .Net 3.5 there is value in returning IEnumerable of items where before one would return a list.

// Take an object and print out the property name and its value
// for all public properties. public static
void DisplayPublicPropertiesAndValues<T>( T target )
{
   foreach (PropertyInfo prp in GetPublic<T>())
      Console.WriteLine( prp.Name + " " + prp.GetValue( target, null ) );
} 

// I have to put things into a list to enumerate over it in the calling method.
public static List<PropertyInfo> GetPublic<T>()
{
   List<PropertyInfo> retList = new List<PropertyInfo>();     

   foreach (PropertyInfo prp in typeof( T ).GetProperties())
      if (prp.PropertyType == typeof( string ))
         retList.Add( prp );     

   return retList;
}

For example in 2.0 I would have to return a List<> of objects to accommodate my foreach needs such as found in GetPublic when I was reflecting off of a objects instance.

Now we return IEnumerable<> thanks to Linq and let it do the work for you. The above GetPublic in .Net 3.5 looks like this:

public static IEnumerable<PropertyInfo> GetPublicV2<T>()
{
    return (from p in typeof( T ).GetProperties()
           where p.PropertyType == typeof( string )
           select p) // Returns IQueryable
           .ToList();  // Otherwise we would be returning IQueryable so change it to a List to get the data.
}

// Same as above but using the extension methods
public static IEnumerable<PropertyInfo> GetPublicV3<T>()
{
    return typeof( T ).GetProperties()
                      .Where( p => p.PropertyType == typeof( string ))
                      .ToList(); // Otherwise we would be returning IQueryable

}

// As I would actually do it now in 2011
public static IList<PropertyInfo> GetPublicV4<T>()
{
    return typeof( T ).GetProperties()
                      .Where( p => p.PropertyType == typeof( string ) )
                      .ToList(); // Otherwise we would be returning IQueryable

}

A lot nicer. We achieved the same functionality but we don’t have to do the dirty work of creating a List! So advice…get used to working with IEnumerable<>.

Share

Tags:

.Net Reflection 101: Accessing The String Properties of an Active Object

Part of why I write some of these articles are to remind myself on how to do things. If one doesn’t do them every day they get lost with the rest of life’s memories. One of the topics I run into every so often is the need to enumerate an object and extract or set values of its properties. In this example I will create a generic function which will take in a class object and write out all of the public properties, the set those public properties.

Example

Here is the class we will reflect and notice it contains public and private properties.

The following code demonstrates how to enumerate over an object, list its properties and their values. It is divided into three static methods.
  1. The first method TestIT is the actual test method which can be called to show the operations for it creates a TestClass object to be reflected. This is used only for debug / show purposes.
  2. The second static OutputProperties shows the differences in how reflection of a class can change the values and a gotcha which gets all developers.
  3. The final method  EnumerateProperties simply enumerates over the reflected properties and prints them out.
public static void TestIT()
{
     TestClass tc = new TestClass( "AValue", "BValue", "CValue" );

     OutputProperties<TestClass>( tc );

     Console.WriteLine( Environment.NewLine );
}

public static void  OutputProperties<T>( T target )
{
     Type targetType = target.GetType();

     PropertyInfo[] propertiesdefaultPublic, propertiesSameAsDefault, propertiesPublicPrivate;

     propertiesdefaultPublic = targetType.GetProperties( );
     propertiesSameAsDefault = targetType.GetProperties( BindingFlags.Instance | BindingFlags.Public );
     propertiesPublicPrivate = targetType.GetProperties( BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic );

     EnumerateProperties<T>( target, propertiesdefaultPublic, "Default -> ()" );
     EnumerateProperties<T>( target, propertiesSameAsDefault, "Same as Default"   );
     EnumerateProperties<T>( target, propertiesPublicPrivate, "Public And Private"  );
}

private static void EnumerateProperties<T>( T target, PropertyInfo[] properties, string Title )
{
 Console.WriteLine( "{0}------- {1} --------{0}", Environment.NewLine, Title );
 foreach (PropertyInfo prp in properties)
 {
     if (prp.PropertyType == typeof( string ))
         Console.WriteLine( string.Format( "({0}):  {1}", prp.Name, prp.GetValue( target, null ) ) );
 }
}
  • Line 03: Creates the target instance with three values to fill the properties.
  • Line 10: This generic method takes the class type and and actual instance of the type.
  • Line 12: What are we looking at? GetType tells us that.
  • Line 16: Here is the big gotcha! Everyone calls the default incarnation which only returns public properties!
  • Line 17: To achieve what the default does, we have to add two different flags. The key one is instance or we won’t reflect anything!
  • Line 18: This is the call which will get the private and public properties…avoids the gotcha of calling the default.
  • Line 26: We will display the properties and data of the instanced class T.
  • Line 29: Enumerate over the properties of the *TYPE*. This is not the actual instance.
  • Line 31: Only do the strings.
  • Line 32: prp.Name gets the name of the property. While GetValue requires that we pass in the actual instantiated object instance to see an actual values. Null is used because we don’t have an indexed type. Its just a string.

Here is the output:

------- Default -> () --------
(AProp):  AValue
(BProp):  BValue

------- Same as Default --------
(AProp):  AValue
(BProp):  BValue

------- Public And Private --------
(AProp):  AValue
(BProp):  BValue
(CProp):  CValue

To set a value, that is the reverse of GetValue which is found by SetValue below and has the same prerequisites:

private static void SetProperties<T>( T target, PropertyInfo[] properties )
{
    int count = 0;

    foreach (PropertyInfo prp in properties)
        prp.SetValue( target, string.Format( "NewValue{0}", ++count ), null );

}

If we were to do a run by just using the Public and Private properties array as used above gives us the below. The first print out set is what was above with our default values. The second after the call to SetProperties example above which has changed the values:

------- Public And Private --------
(AProp):  AValue
(BProp):  BValue
(CProp):  CValue

Call to SetValue() and the GetValue():

------- Public And Private --------

(AProp):  NewValue1
(BProp):  NewValue2
(CProp):  NewValue3
Share

Tags: ,

Reflect Interface from Unknown Assembly in C#

I had a need to scan a directory for assemblies and load (instantiate) a specific interface from the foreign assembly. The idea was that the application would work with a plugin architecture which would allow for an outside foreign assembly to be dropped in. Upon startup, the application would look into the directory and instantiate the plugin via its interface. (Note this is .Net 2 code and .Net 3.5 has a plugin architecture but the concepts of reflection are what are important in this article).

The following code will accept a filename of the assembly and attempt to load the interface in question. If it succeeds it returns the interface:

private IPlugin LoadPlugin( string AssemblyFileName )
{
 IPlugin PluginFound = null;
 Type iPluginType = typeof(IPlugin);

 Assembly _Assembly = Assembly.LoadFrom(AssemblyFileName);

 if (_Assembly != null)
 {
   Type[] types = _Assembly.GetExportedTypes();

   foreach (Type t in types)
    if (iPluginType.IsAssignableFrom(t))
    {
     IPlugin operation = Activator.CreateInstance(t) as IPlugin;

     if (operation != null) // Found!
     {
       PluginFound = operation;
       break;
     }
    }
   }

   return PluginFound;
  }
}

Here is what is going on:

  • Line 1 : The fully qualified filename is passed into the method.
  • Line 3 : The instantiated object if found, to be returned in this reference.
  • Line 4 : The actual type we are interested in.
  • Line 10 : Reflect the types found in the foreign assembly.
  • Line 13 : Is the current type the same as what we are looking for?
  • Line 15 : Try creating an instance.
  • Line 17 : Test the cast from line 15. If it is not null. We have a valid instance.
Share

Tags: , , ,

Dynamic Reflection and Instantiation of an Object at Runtime in .Net

This article shows how one can create and use objects on the fly through reflection in .Net. I will create a class which looks like this:

public class DynamicClass
{
    public void Show()
    {
        Console.WriteLine("Success!");
    }

}

The goal is to reflect the class at runtime, simulating getting the class type in a  string and then using the reflected instantiated object. The below code will do that.

using System.Reflection;

...

// This is the full namespaced path to my class
string targetType = "ConsoleApplication1.Test_Classes.DynamicClass";

Type reflectedType = Type.GetType(targetType);

object obj = Activator.CreateInstance(reflectedType);

DynamicClass theClass = obj as DynamicClass;

if (theClass != null)
{
    theClass.Show();
}
else
    Console.WriteLine("Failed!");

Here is the rundown of what happened

  • Line 1 : Include the reflection namespace for this magic to work.
  • Line 6 : Simulates getting the name of the object dynamically. This is the fully qualified path.
  • Line 8 : Convert the string name to an object Type.
  • Line 10 : Actually create the instance. Since our object did not have any constructor arguments or job is easier.
  • Line 12 : Do we really have a new instance of the class?
  • Line 14 : Check if it is not null. If it is not, call show which in this case will tell us it worked!
  • Line 19 : Something is wrong and the class was not created if this is hit.

Now we have the class and can operate on it as if we new’ed it up. If one has trouble determining the proper name or arguments try this trick:

Type DCType = typeof(DynamicClass);
string targetType = DCType.ToString();

// Prints out "Name: ConsoleApplication1.Test_Classes.DynamicClass"
Console.WriteLine("Name: {0}{1}", targetType, Environment.NewLine);

That works well for working with generics which have there own specifications one has to deal with generic types such as dictionary:

Dictionary<string,string> myDict = new Dictionary<string,string>();

// Prints out:
// Name: System.Collections.Generic.Dictionary`2[System.String,System.String]
Console.WriteLine("Name: {0}{1}",
   myDict.GetType().ToString(),
   Environment.NewLine);
Share

C#: Using Reflection to Instantiate a Generic Class in .Net

Reflection has many purposes, but what happens if one wants to instantiate a generic class? How does one specify the what makes the class generic to  instantiate it? The trick is to use the MakeGenericType to make the argument(s) and then call create Instance. Here is a code snippet:

Type d1 = typeof(List<>);

Type[] typeArgs = { typeof(string) };

Type makeme = d1.MakeGenericType(typeArgs);

object o = Activator.CreateInstance(makeme);

List<string> itsMe = o as List<string>;

Console.WriteLine((itsMe == null) ? "Failed" : "Succeeded");

Here is what is going on

  • Line 1 We get the type as normal.
  • Line 3 Create an array of the arguments we are interested in.
  • Line 5 Call MakeGenericType to do the magic
  • Line 7 Create the object.
Share

Tags: , ,

C# Using Extended Attribute Information on Objects

Update 5/26/2014 : Added Enum Extension to Extract Custom Attribute.

I use this trick in .Net to extensively Trojan Horse extra meta type information on any object. At run time I reflect off of the object and extract this information which was placed on it. Below I show how to do it on an enum using a built in attribute in .Net and secondly I show how to create your own custom attribute. Note: in the example is an enum, but one can decorate any object with the attribute.

Single Attribute Values

The first way which will be shown is done using C#’s description attribute found in the System.ComponentModel namespace and does not require any special coding such as creating a class definition for the attribute. The second way shows a more robust custom attribute which has more specialized information.

Step 1 Include these namespaces:

using System.Reflection;
using System.ComponentModel;

Step 2 Decorate the enums with the Description Attribute

public enum EPortalErrors
{
  [Description("Internal programming error")]
  InternalError,
  [Description("Invalid request Xml: Reset XSLT.")]
  InvalidXmlSentIn,
}

Step 3 Create a static method to divine the attribute description

/// <summary>If an attribute such as is on an enumeration exists, this will return that
/// information</summary>
/// <param name="value">The object which has the attribute.</param>
/// <returns>The description string of the attribute or string.empty</returns>
public static string GetAttributeDescription( object value )
{
    string retVal = string.Empty;
    try
    {
        FieldInfo fieldInfo = value.GetType().GetField(value.ToString());

        DescriptionAttribute[] attributes =
           (DescriptionAttribute[])fieldInfo.GetCustomAttributes
           (typeof(DescriptionAttribute), false);

        retVal = ( ( attributes.Length > 0 ) ? attributes[0].Description : value.ToString() );
    }
    catch (NullReferenceException)
    {
     //Occurs when we attempt to get description of an enum value that does not exist
    }
    finally
    {
        if (string.IsNullOrEmpty(retVal))
            retVal = "Unknown";
    }    

    return retVal;
}

Step 4 Call GetAttributeDescription with the enum in hand and we will get the extended text. Done…


Multiple Attribute Values

That first method is is nice for basic information, but what if one needs more information? That can be done by writing a custom attribute information extraction class. We will start at step 2 from above:

Step 2 Determine what items should be on the attribute and create an attribute name. In the below example we want to decorate the enum with three integers and another enum. This extended information will allow for other processing to occur which is dependant on that info. Our attribute name is DatabaseConnection which will mirror our attribute extraction class

public enum EActivities
{
   HoldingsGet,

    /// <summary>We need to inform the DAL that the primary keys are 1,2,3 and
    /// that we only want one column</summary>
   [DatabaseConnection(1,2,3, DatabaseConnectionAttribute.Columns.OneColumn)]
   OpsDBAttributionBatchCodes,
}

Step 3 Create a static method to divine the attribute description for DatabaseConnection. Note there is other activities/properties that are shown, for the consumer can get the extended int info in a list. Note also we have to decorate the class with an attribute to let the system know that this class will be used as an attribute

/// <summary>When using Enums for exceptions this attribute provides more information
/// to describe the enumeration such as target fields and primary keys.</summary>
[AttributeUsage(AttributeTargets.Field)]
public class DatabaseConnectionAttribute : Attribute
{

    #region Construction    

    /// <summary>Used to specify the needed columns.</summary>
    public enum Columns : int
    {
        OneColumn = 1,
        TwoColumns = 2,
        ThreeColumns = 3,
        FourColumns = 4,
        FiveColumns = 5,
        SixColumns = 6
    }

    /// <summary>Allow a consumer to specify an attribute with for data items.</summary>
    public DatabaseConnectionAttribute(int pkey1, int pkey2, int pkey3, DatabaseConnectionAttribute.Columns columns)
    {
        pkeys.Add(pkey1);
        pkeys.Add(pkey2);
        pkeys.Add(pkey3);
        _Columns = columns;
    }

    #endregion
    #region Properties
    /// <summary>To total number of columns to extract from the database.</summary>
    public DatabaseConnectionAttribute.Columns ColumnsNeeded
    {
        get { return _Columns; }
    }    

    /// <summary>Retrieves the list of primary keys.</summary>
    public List<int> PrimaryKeys
    {
        get { return pkeys; }
    }

    #endregion    

    #region Exposed Static Functionality

    /// <summary>This method will peer into an enum and extract this class if it exists.</summary>
    /// <param name="enumItem">The enumeration which contains the DatabaseConnectionAttribute.</param>
    /// <returns>The current object or null</returns>
    public static DatabaseConnectionAttribute ExtractAttribute(object enumItem)
    {
        DatabaseConnectionAttribute retVal = null;

        try
        {
            FieldInfo fieldInfo = enumItem.GetType().GetField(enumItem.ToString());
            DatabaseConnectionAttribute[] attributes =
                (DatabaseConnectionAttribute[])fieldInfo.GetCustomAttributes
                (typeof(DatabaseConnectionAttribute), false);

            if (attributes != null)
                if (attributes.Length > 0)
                    retVal = attributes[0];
        }
        catch (NullReferenceException)
        {
            //Occurs when we attempt to get description of an enum value that does not exist
        }

        return retVal;
    }
    #endregion

    #region Variables
    /// <summary>Holds the primary key information.</summary>
    List<int> pkeys = new List<int>();    

    /// <summary>What columns are required by the user.</summary>
    private DatabaseConnectionAttribute.Columns _Columns;
    #endregion

}

Step 4 Now by calling the static ExtractAttribute we are returned an object that has all of the information off of the enum. Quite handy.


 

Update: Extracting Custom Attribute using a Generic Extension.

Use this code to extract your custom extension. In the below example we use the custom extension to get the custom attribute, of the enum defined above and its custom attribute.

DatabaseConnectionAttribute custAttr = 

    EActivities.OpsDBAttributionBatchCodes
               .ExtractAttribute<DatabaseConnectionAttribute, EActivities>();

Extension Method Code

/// <summary>
/// If an enum has a custom attrbute, this will returrn that attribute or null.
/// </summary>
/// <typeparam name="TCustomAttr">The type of the custom attribute to extract from the enum.</typeparam>
/// <typeparam name="TEnumItance">The enum currently being viewed..</typeparam>
/// <param name="instance">The instance.</param>
/// <returns>The custom attribute (TCustomAttr) or null</returns>
public static TCustomAttr ExtractAttribute<TCustomAttr, TEnum>(this TEnum instance)
{
    if (instance != null)
    {
        try
        {
            FieldInfo fieldInfo = instance.GetType()
                                          .GetField(instance.ToString());

            var attributes = fieldInfo.GetCustomAttributes(typeof(TCustomAttr), false)
                                      .ToList();

            if (attributes.Any())
                return (TCustomAttr)attributes[0];

        }
        catch (Exception)
        {
        }
    }

    return default(TCustomAttr);
}
Share

Tags: