I have been using CSLA 3.8.2 w/VB in a new application. I had been using syntax from CSLA 2.0 for properties and decided to switch to the new PropertyInfo method. I rewrote a lot of code, but when I tried running it I received the error
{"The type initializer for 'EPM.Library.OwnerBase' threw an exception."}
{"Can not register property OwnerID after containing type (Entity) has been instantiated"}
I tried this with and without the ForceInit hack with no changes (is it still necessary in 3.8.2?)
My inheritance looks like this
BusinessBase
Entity
OwnerBase
Owner
There are PropertyInfo statements in the Entity and the OwnerBase classes. Entity is used by most of my classes so it is likely that another class derived from it would have been already created the Shared PropertyInfo's in Entity (which I assume would not be a problem).
I have tried to step the code, but it never reaches the New() routine of the Owner object so I assume this is being thrown by CSLA when it hits the first PropertyInfo in OwnerBase. How do I go about finding the problem?
I have a shared function in Owner (GetByID) that is called to retrieve the object. I have
Dim obj as Owner
obj = Owner.GetByID(1234)
The exception throws on the GetByID, and a breakpoint at the beginning of it never hits.
Any help on how to fix this would be greatly appreciated.
Gary P
Are you using the lambda overloads for RegisterProperty()? If not, are your type parameters correct? That's the most common mistake.
If you are in .NET, the forceInit trick shouldn't be necessary. If you are in SL the forceInit trick shouldn't be necessary if your PropertyInfo(Of T) fields are public.
I'm not sure what you mean by "lamda overloads". The RegisterProperty's in the classes look like this:
Protected Shared CodeProperty As PropertyInfo(Of String) = RegisterProperty(New PropertyInfo(Of String)("Code"))
Is there something more needed? I am notusing LINQ for DB access currently. I'll make them all Public, if that will help. The project is WinForms.
The error is thrown in PropertyInfoManager.cs, RegisterProperty<T>. Returning true on IsLocked. It is looking at the Cache for the Inherited Entity object rather than the Owner object.
Thanks for the AMAZINGLY quick response.
Hi,
remember that all the classes in your hierarchy have to be generic...
Are they?
Stefan
Stefan,
Hmmm.
They currently look like this (all are marked Serializable):
Public MustInherit Class Entity
Inherits BusinessBase(Of Entity)
Protected Shared PropertyInfos here
Partial Public Class OwnerBase
Inherits Entity
Additional Protected Shared PropertyInfos here (erroring on these)
Public Class Owner
Inherits OwnerBase
Possibly some here too.
Is that somehow the problem? (This was not a problem before switching to the PropertyInfo template)
Thanks
Stefan,
After rereading your post I went back to Rocky's book. On page 239-240 (where he discusses inheritance and the Shared Field problem) there is reference to custom base classes (which I assume is what I have going here). In the book it shows a custom base class defined as follows:
<Serializable()> _
Public MustInherit Class CustomBase(Of T As CustomBase(Of T))
Inherits BuisinessBase(Of T)
Is that what you are referring to? That in my case I would need to apply this syntax to the Entity and OwnerBase Classes? If so, don't I lose the ability to access each of my derived classes as a generic Entity? I have many routines that operate on an Entity whether that be an Owner, Vendor, Order, etc. and I REALLY don't want to have to rewrite all those (and all the calls to them) as Generics too.
Or, I may be confused about exactly how generics work.
And thanks for your quick response too. I'm staring to feel like I may have to abandon the PropertyInfo idea and go back to handling all my own property changes like we did in CSLA 2.0 unless there is some way to get the same functionality.
Copyright (c) Marimer LLC