For various reasons, I am trying to create 3 base objects that all root, list and business objects inherit from. So I would have:
For Business Objects: BusinessBase(Of T)<-CSLAComponentBase(Of T As BusinessBase(Of T))<-ConcreteBO
For Lists of Business Objects: BusinessBindingListBase(Of L, C)<-CSLAListBase(Of L As BusinessBindingListBase(Of L, C), C As CSLAComponentBase(Of C))<-ConcreateListOfBOs
For Root Business Object: BusinessBase(Of CSLARootBase(Of L, C))<-CSLARootBase(Of L As {CSLARootBase(Of L, C), New}, C As CSLAComponentBase(Of C))<-ConcreateRootBO
I have confirmed that when I want to load just a BO, it works. But when I try to load the RootBO, it fails.
Exception: {"The type initializer for 'JonasNET.Master.CSLARootBase`2' threw an exception."}
Inner Exception: {"The type initializer for 'JonasNET.Master.CSLARootBase`2' threw an exception."}
Inner Inner Exception: {"Not a member access Parameter name: member"}
I get this when calling rootBO.MaintainList, which calls FieldManager.FieldExists(MaintainListProperty). I've included all the important bits of the CSLARootBase. If there are other bits anybody needs, I can add them to the post.
Public MustInherit Class CSLARootBase(Of L As {CSLARootBase(Of L, C), New}, C As CSLAComponentBase(Of C))
Inherits BusinessBase(Of CSLARootBase(Of L, C))
Public Sub New(Optional ByVal RootCompany As Long = Nothing)
If (Not RootCompany = 0) Then
CompanyId = RootCompany
End If
End Sub
Public Shared CompanyIdProperty As PropertyInfo(Of Integer) = RegisterProperty(Of Integer)(Function(p) p.CompanyId)
''' <summary>
''' Gets or sets the company id.
''' </summary>
''' <value>
''' The company id.
''' </value>
Public Property CompanyId() As Integer
Get
Return GetProperty(CompanyIdProperty)
End Get
Set(ByVal value As Integer)
SetProperty(CompanyIdProperty, value)
End Set
End Property
''' <summary>
''' Gets the children. Called from CSLA
''' </summary>
'''
Public ReadOnly Property Children() As SortedBindingList(Of C)
Get
Return New SortedBindingList(Of C)(MaintainList)
End Get
End Property
Public Shared MaintainListProperty As PropertyInfo(Of L) = RegisterProperty(Of L)(Function(p) p.MaintainList, RelationshipTypes.LazyLoad)
''' <summary>
''' Gets the list of BOs which is accessed by the maintain controls.
''' </summary>
Public Overridable Function MaintainList(Optional ByVal CompanyID As Long = Nothing, Optional ByVal SortColumn As String = Nothing, Optional ByVal StartRecord As Integer = 0, Optional ByVal MaxRecords As Integer = 0) As L
' TODO: Do something with all the optional parameters. Add criteria
If Not FieldManager.FieldExists(MaintainListProperty) Then
LoadProperty(Of L)(MaintainListProperty, New L())
End If
Return GetProperty(Of L)(MaintainListProperty)
End Function
End Class
So as an experiment, I actually changed my code so that it no longer used the Generic root object, just to see if it worked. So now it (temporarily) looks like:
For Lists of Business Objects: BusinessBindingListBase(Of L, C)<-CSLAListBase(Of L As BusinessBindingListBase(Of L, C), C As CSLAComponentBase(Of C))<-ConcreateListOfBOs
For Root Business Object: BusinessBase(Of ConcreateRootBO)<-ConcreteRootBO.
I was surprised, but I actually got a similar exception.
Exception: {"DataPortal.Create failed (System.ArgumentException: Not a member access
Parameter name: member
at Csla.Reflection.Reflect`1.GetMemberInfo(Expression member)
at Csla.Reflection.Reflect`1.GetProperty(Expression`1 property)
at Csla.BusinessBase`1.RegisterProperty[P](Expression`1 propertyLambdaExpression, RelationshipTypes relationship)
at JonasNET.GL.BL.GLAccountTypeRoot..cctor() in C:\TFS\JonasNET-CSLA\JonasNET.GL.BL\Classes\GLAccountTypeRoot.vb:line 79)"}
Inner Exception: {"The type initializer for 'JonasNET.GL.BL.GLAccountTypeRoot' threw an exception."}
Inner Inner Exception: {"Not a member access
Parameter name: member"}
So I guess the error is not because it's generic, but something else.
You should always make sure to call the default constructor (that in turn should call base class contructor).
This is vital to init the object like registering properties/business rules and initializing FieldDataManager.
Public Sub New(Optional ByVal RootCompany As Long = Nothing)
Me.New() ' or MyBase.New()
If (Not RootCompany = 0) Then
CompanyId = RootCompany
End If
End Sub
Copyright (c) Marimer LLC