matthew.abercrombie
Member
- Joined
- May 28, 2010
- Messages
- 5
- Programming Experience
- 5-10
I'm building an abstract class that handles some common operations for all of my data access objects. The class will utilize generics, so I can't make direct calls to constructors, business object properties, etc. Reflection is way too slow for what I want to accomplish, so I am using a DynamicMethod, ILGenerator, and Delegate caching instead (sample will follow).
The method I'm currently working on is a Private Shared method that populates a list of business objects using records from a data table. I'm having a problem building the property setter via IL. I'm getting an object reference error, but I'm not sure how to fix it. I believe the error comes from the "target" being Nothing, but the parameter I'm passing as the target is not Nothing at the time of invocation. Here are some snippets of what I've got so far:
I'm assuming the obj is not being passed correctly as the target, thus causing the target to be Nothing. Please advise.
The method I'm currently working on is a Private Shared method that populates a list of business objects using records from a data table. I'm having a problem building the property setter via IL. I'm getting an object reference error, but I'm not sure how to fix it. I believe the error comes from the "target" being Nothing, but the parameter I'm passing as the target is not Nothing at the time of invocation. Here are some snippets of what I've got so far:
VB.NET:
'class declaration -- TList is strongly-typed list of T
Public MustInherit Class DataAccessBase(Of T, TList)
...
'delegate declaration
Delegate Sub GenericSetter(ByVal target As Object, ByVal value As Object)
...
'method to obtain delegate instance to be stored in cache
Private Shared Function CreateSetMethod(ByVal pInfo As PropertyInfo) As GenericSetter
Dim setDelegate As GenericSetter = Nothing
Try
'get the set method from the property info
Dim setmethod As MethodInfo = pInfo.GetSetMethod
'if no setter, return nothing
If setmethod Is Nothing Then
Return Nothing
End If
'create the dynamic method
Dim args As Type() = New Type() {GetType(Object), GetType(Object)}
Dim setter As New DynamicMethod("_set" + pInfo.Name, Nothing, args, pInfo.DeclaringType)
Dim ILGen As ILGenerator = setter.GetILGenerator
ILGen.Emit(OpCodes.Ldarg_0)
ILGen.Emit(OpCodes.Castclass, pInfo.DeclaringType)
ILGen.Emit(OpCodes.Ldarg_1)
If pInfo.PropertyType.IsClass Then
ILGen.Emit(OpCodes.Castclass, pInfo.PropertyType)
Else
ILGen.Emit(OpCodes.Unbox_Any, pInfo.PropertyType)
End If
ILGen.EmitCall(OpCodes.Callvirt, setter, Nothing)
ILGen.Emit(OpCodes.Ret)
'create the delegate and return it
setDelegate = CType(setter.CreateDelegate(GetType(GenericSetter)), GenericSetter)
Catch ex As Exception
Throw New Exception(ex.ToString)
End Try
Return setDelegate
End Function
...
'method to populate the business object using the cache -- this is where
'the exception is thrown - within the contents of the IF statement and I
'have made sure that obj and SetterCache.Item(pInfo) is not nothing
Protected Shared Sub PopulateObject(ByRef obj As T, ByVal r As DataRow)
Try
For Each pInfo As PropertyInfo In obj.GetType.GetProperties
If r.Table.Columns.Contains(pInfo.Name) AndAlso Not IsDBNull(r(pInfo.Name)) Then
'EXCEPTION THROWN HERE...
CType(SetterCache.Item(pInfo), GenericSetter)(obj, r(pInfo.Name))
End If
Next
Catch ex As Exception
Throw New Exception(ex.ToString)
End Try
End Sub
I'm assuming the obj is not being passed correctly as the target, thus causing the target to be Nothing. Please advise.