using System;
using System.Data;
using System.Reflection;
using System.Collections.Generic;
namespace ReportEngine
{
class Program
{
static void Main(string[] args)
{
DataTable table = InputGeneration.GetTable();
//InputGeneration.DisplayTable(table);
#region "Method2 - Generate class and properties alone at
runtime"
Console.WriteLine("\n---Method2
- Generate class and properties alone at runtime--------------\n");
IEnumerableDynamicProperty > properties = Method2.GenerateProperties(table);
Type type = Method2.GenerateClass(properties);
//The below combination will return all non-public instance
properties on the type.
var flags = BindingFlags.Instance
| BindingFlags.Public | BindingFlags.NonPublic;
PropertyInfo[] props = type.GetProperties(flags);
for (int i = 0; i
< props.Length; i++)
{
Console.Write("\t{0}\t",
props[i].Name);
}
Console.WriteLine("\t");
Method2 m2 = new Method2();
m2.AssignClassValues(type, table);
#endregion
Console.WriteLine("\n---------------------------------------------------------\n");
Console.ReadLine();
}
}
}
InputGeneration:
using System;
using System.Data;
namespace ReportEngine
{
public static class InputGeneration
{
public static DataTable GetTable()
{
//
// Here we create a DataTable with four columns.
//
DataTable table = new
DataTable();
table.Columns.Add("Dosage",
typeof(int));
table.Columns.Add("Drug", typeof(string));
table.Columns.Add("Patient",
typeof(string));
table.Columns.Add("Date", typeof(DateTime));
//
// Here we add five DataRows.
//
table.Rows.Add(25, "Indocin",
"David", DateTime.Now);
table.Rows.Add(50, "Enebrel",
"Sam", DateTime.Now);
table.Rows.Add(10, "Hydralazine",
"Christoff", DateTime.Now);
table.Rows.Add(21, "Combivent",
"Janet", DateTime.Now);
table.Rows.Add(100, "Dilantin",
"Melanie", DateTime.Now);
return table;
}
public static void DisplayTable(DataTable
dt)
{
if (dt.Rows.Count > 0)
{
foreach (DataColumn
column in dt.Columns)
{
Console.Write("\t{0}\t",
column.ColumnName);
}
Console.WriteLine("\t");
foreach (DataRow
row in dt.Rows)
{
foreach (DataColumn
column in dt.Columns)
Console.Write("\t{0}\t", row[column]);
Console.WriteLine("\t");
}
}
else
Console.WriteLine("No
Current Rows Found");
}
}
}
Method2:
using System;
using System.Data;
using System.Collections.Generic;
using ReportEngine.ClassAtRuntime;
using System.Reflection;
namespace ReportEngine
{
public class Method2
{
public static IEnumerable<DynamicProperty>
GenerateProperties(DataTable table)
{
List<DynamicProperty>
Properties = new List<DynamicProperty>();
foreach (DataColumn
column in table.Columns)
{
Properties.Add(new DynamicProperty(column.ColumnName.ToUpper(),
column.DataType));
}
return Properties;
}
public static Type GenerateClass(IEnumerable<DynamicProperty> properties)
{
Type type = Dynamic.CreateClass(properties);
return type;
}
public void
AssignClassValues(Type type, DataTable table)
{
List<object>
lstobj = new List<object>();
foreach (DataRow
dr in table.Rows)
{
var obj = Activator.CreateInstance(type);
PropertyInfo[] props =
obj.GetType().GetProperties();
for (int i = 0; i
< props.Length; i++)
{
if (props[i].CanWrite)
{
try
{
if (dr[props[i].Name] != null && !dr.IsNull(props[i].Name))
{
props[i].SetValue(obj, dr[props[i].Name], null);
}
else
{
props[i].SetValue(props[i].Name, null, null);
}
}
catch // DB COLUMN does not exist for this property.
{
props[i].SetValue(props[i].Name, null, null);
}
}
}
lstobj.Add(obj);
}
}
public void
ReadClassValues(List<object> lstobj)
{
foreach (object obj in lstobj)
{
}
}
public void
getModelFromObject(Type type, DataTable table)
{
List el = new
List();
foreach (DataRow
dr in table.Rows)
{
T item
= (T)Activator.CreateInstance(type);
getObject(dr, ref item, table);
T tsts
= item;
((List)el).Add(item);
}
}
public void
getObject(DataRow dr, ref T obj, DataTable
dt)
{
foreach (DataColumn
dc in dt.Columns)
{
if (obj.GetType().GetProperty(dc.ColumnName) != null)
{
obj.GetType().GetProperty(dc.ColumnName).SetValue(obj,
dr[dc.ColumnName], null);
}
}
}
}
}
DynamicClasswithProperties:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Reflection.Emit;
using System.Threading;
namespace ReportEngine.ClassAtRuntime
{
class DynamicClasswithProperties
{
}
public abstract class DynamicClass
{
public override string ToString()
{
PropertyInfo[] props = this.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
StringBuilder sb = new
StringBuilder();
sb.Append("{");
for (int i = 0; i
< props.Length; i++)
{
if (i > 0) sb.Append(",
");
sb.Append(props[i].Name);
sb.Append("=");
sb.Append(props[i].GetValue(this, null));
}
sb.Append("}");
return sb.ToString();
}
}
public class DynamicProperty
{
string name;
Type type;
public DynamicProperty(string
name, Type type)
{
if (name == null) throw new ArgumentNullException("name");
if (type == null) throw new ArgumentNullException("type");
this.name = name;
this.type = type;
}
public string Name
{
get { return name; }
}
public Type Type
{
get { return type; }
}
}
public static class Dynamic
{
public static Type CreateClass(IEnumerable<DynamicProperty> properties)
{
return ClassFactory.Instance.GetDynamicClass(properties);
}
}
internal class Signature : IEquatable<Signature>
{
public DynamicProperty[]
properties;
public int hashCode;
public Signature(IEnumerable<DynamicProperty> properties)
{
this.properties = properties.ToArray();
hashCode =
0;
foreach (DynamicProperty
p in properties)
{
hashCode ^= p.Name.GetHashCode() ^ p.Type.GetHashCode();
}
}
public override int GetHashCode()
{
return hashCode;
}
public override bool Equals(object
obj)
{
return obj is Signature ? Equals((Signature)obj)
: false;
}
public bool Equals(Signature other)
{
if (properties.Length != other.properties.Length) return false;
for (int i = 0; i
< properties.Length; i++)
{
if (properties[i].Name != other.properties[i].Name ||
properties[i].Type != other.properties[i].Type) return
false;
}
return true;
}
}
internal class ClassFactory
{
public static readonly ClassFactory
Instance = new ClassFactory();
static ClassFactory() { } // Trigger lazy
initialization of static fields
ModuleBuilder module;
Dictionary<Signature,
Type> classes;
int classCount;
ReaderWriterLock rwLock;
private
ClassFactory()
{
AssemblyName name = new
AssemblyName("DynamicClasses");
AssemblyBuilder assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run);
#if ENABLE_LINQ_PARTIAL_TRUST
new ReflectionPermission(PermissionState.Unrestricted).Assert();
#endif
try
{
module
= assembly.DefineDynamicModule("Module");
}
finally
{
#if ENABLE_LINQ_PARTIAL_TRUST
PermissionSet.RevertAssert();
#endif
}
classes = new Dictionary<Signature, Type>();
rwLock = new ReaderWriterLock();
}
public Type GetDynamicClass(IEnumerable<DynamicProperty>
properties)
{
rwLock.AcquireReaderLock(Timeout.Infinite);
try
{
Signature signature = new
Signature(properties);
Type type;
if
(!classes.TryGetValue(signature, out type))
{
type = CreateDynamicClass(signature.properties);
classes.Add(signature, type);
}
return type;
}
finally
{
rwLock.ReleaseReaderLock();
}
}
Type CreateDynamicClass(DynamicProperty[]
properties)
{
LockCookie cookie = rwLock.UpgradeToWriterLock(Timeout.Infinite);
try
{
string typeName = "DynamicClass"
+ (classCount + 1);
#if ENABLE_LINQ_PARTIAL_TRUST
new ReflectionPermission(PermissionState.Unrestricted).Assert();
#endif
try
{
TypeBuilder tb = this.module.DefineType(typeName,
TypeAttributes.Class |
TypeAttributes.Public, typeof(DynamicClass));
FieldInfo[] fields = GenerateProperties(tb,
properties);
GenerateEquals(tb, fields);
GenerateGetHashCode(tb, fields);
Type result = tb.CreateType();
classCount++;
return result;
}
finally
{
#if ENABLE_LINQ_PARTIAL_TRUST
PermissionSet.RevertAssert();
#endif
}
}
finally
{
rwLock.DowngradeFromWriterLock(ref
cookie);
}
}
FieldInfo[] GenerateProperties(TypeBuilder tb, DynamicProperty[]
properties)
{
FieldInfo[] fields = new
FieldBuilder[properties.Length];
for (int i = 0; i
< properties.Length; i++)
{
DynamicProperty dp = properties[i];
FieldBuilder fb = tb.DefineField("_" + dp.Name, dp.Type, FieldAttributes.Private);
PropertyBuilder pb = tb.DefineProperty(dp.Name, PropertyAttributes.HasDefault, dp.Type, null);
MethodBuilder mbGet = tb.DefineMethod("get_" + dp.Name,
MethodAttributes.Public | MethodAttributes.SpecialName
| MethodAttributes.HideBySig,
dp.Type, Type.EmptyTypes);
ILGenerator genGet = mbGet.GetILGenerator();
genGet.Emit(OpCodes.Ldarg_0);
genGet.Emit(OpCodes.Ldfld, fb);
genGet.Emit(OpCodes.Ret);
MethodBuilder
mbSet = tb.DefineMethod("set_" +
dp.Name,
MethodAttributes.Public | MethodAttributes.SpecialName
| MethodAttributes.HideBySig,
null, new Type[] { dp.Type });
ILGenerator genSet = mbSet.GetILGenerator();
genSet.Emit(OpCodes.Ldarg_0);
genSet.Emit(OpCodes.Ldarg_1);
genSet.Emit(OpCodes.Stfld, fb);
genSet.Emit(OpCodes.Ret);
pb.SetGetMethod(mbGet);
pb.SetSetMethod(mbSet);
fields[i] = fb;
}
return fields;
}
void GenerateEquals(TypeBuilder
tb, FieldInfo[] fields)
{
MethodBuilder mb = tb.DefineMethod("Equals",
MethodAttributes.Public
| MethodAttributes.ReuseSlot |
MethodAttributes.Virtual | MethodAttributes.HideBySig,
typeof(bool), new Type[] { typeof(object) });
ILGenerator gen = mb.GetILGenerator();
LocalBuilder
other = gen.DeclareLocal(tb);
Label next = gen.DefineLabel();
gen.Emit(OpCodes.Ldarg_1);
gen.Emit(OpCodes.Isinst, tb);
gen.Emit(OpCodes.Stloc, other);
gen.Emit(OpCodes.Ldloc, other);
gen.Emit(OpCodes.Brtrue_S, next);
gen.Emit(OpCodes.Ldc_I4_0);
gen.Emit(OpCodes.Ret);
gen.MarkLabel(next);
foreach (FieldInfo
field in fields)
{
Type ft = field.FieldType;
Type ct = typeof(EqualityComparer<>).MakeGenericType(ft);
next =
gen.DefineLabel();
gen.EmitCall(OpCodes.Call,
ct.GetMethod("get_Default"), null);
gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Ldfld, field);
gen.Emit(OpCodes.Ldloc, other);
gen.Emit(OpCodes.Ldfld, field);
gen.EmitCall(OpCodes.Callvirt,
ct.GetMethod("Equals", new Type[] { ft,
ft }), null);
gen.Emit(OpCodes.Brtrue_S, next);
gen.Emit(OpCodes.Ldc_I4_0);
gen.Emit(OpCodes.Ret);
gen.MarkLabel(next);
}
gen.Emit(OpCodes.Ldc_I4_1);
gen.Emit(OpCodes.Ret);
}
void GenerateGetHashCode(TypeBuilder
tb, FieldInfo[] fields)
{
MethodBuilder mb = tb.DefineMethod("GetHashCode",
MethodAttributes.Public | MethodAttributes.ReuseSlot
|
MethodAttributes.Virtual | MethodAttributes.HideBySig,
typeof(int), Type.EmptyTypes);
ILGenerator gen = mb.GetILGenerator();
gen.Emit(OpCodes.Ldc_I4_0);
foreach (FieldInfo
field in fields)
{
Type ft = field.FieldType;
Type ct = typeof(EqualityComparer<>).MakeGenericType(ft);
gen.EmitCall(OpCodes.Call,
ct.GetMethod("get_Default"), null);
gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Ldfld, field);
gen.EmitCall(OpCodes.Callvirt,
ct.GetMethod("GetHashCode", new Type[] { ft
}), null);
gen.Emit(OpCodes.Xor);
}
gen.Emit(OpCodes.Ret);
}
}
}
No comments:
Post a Comment