|
Imports System.Data.SqlClient
Imports System.Reflection
Imports System.Reflection.Emit
Imports System.Data
Public Class DynamicBuilder(Of T)
Private Shared ReadOnly getValueMethod As MethodInfo = GetType(IDataRecord).GetMethod("get_Item", New Type() {GetType(Integer)})
Private Shared ReadOnly isDBNullMethod As MethodInfo = GetType(IDataRecord).GetMethod("IsDBNull", New Type() {GetType(Integer)})
Private Delegate Function Load(ByVal dataRecord As IDataRecord) As T
Private handler As Load
Private Sub DynamicBuilder()
End Sub
Public Function Build(ByVal dataRecord As IDataRecord) As T
Return handler(dataRecord)
End Function
Public Shared Function CreateBuilder(ByVal dataRecord As IDataRecord) As DynamicBuilder(Of T)
Dim dynamicBuilder As DynamicBuilder(Of T) = New DynamicBuilder(Of T)()
Dim i As Integer
Dim method As DynamicMethod = New DynamicMethod("DynamicCreate", GetType(T), New Type() {GetType(IDataRecord)}, GetType(T), True)
Dim generator As ILGenerator = method.GetILGenerator()
Dim result As LocalBuilder = generator.DeclareLocal(GetType(T))
generator.Emit(OpCodes.Newobj, GetType(T).GetConstructor(Type.EmptyTypes))
generator.Emit(OpCodes.Stloc, result)
For i = 0 To dataRecord.FieldCount - 1
Dim propertyInfo As PropertyInfo = GetType(T).GetProperty(dataRecord.GetName(i))
Dim endIfLabel As Label = generator.DefineLabel()
If Not propertyInfo Is Nothing Then
If Not propertyInfo.GetSetMethod() Is Nothing Then
generator.Emit(OpCodes.Ldarg_0)
generator.Emit(OpCodes.Ldc_I4, i)
generator.Emit(OpCodes.Callvirt, isDBNullMethod)
generator.Emit(OpCodes.Brtrue, endIfLabel)
generator.Emit(OpCodes.Ldloc, result)
generator.Emit(OpCodes.Ldarg_0)
generator.Emit(OpCodes.Ldc_I4, i)
generator.Emit(OpCodes.Callvirt, getValueMethod)
generator.Emit(OpCodes.Unbox_Any, dataRecord.GetFieldType(i))
generator.Emit(OpCodes.Callvirt, propertyInfo.GetSetMethod())
generator.MarkLabel(endIfLabel)
End If
End If
Next
generator.Emit(OpCodes.Ldloc, result)
generator.Emit(OpCodes.Ret)
dynamicBuilder.handler = CType(method.CreateDelegate(GetType(Load)), Load)
Return dynamicBuilder
End Function
End Class
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.