I've recently upgraded from CSLA 3.8.2 to CSLA 4 Beta 1, and I have been hitting a runtime error in my code. I have a base class that has a CSLA property on it and is using the forceInit trick to ensure static initialization. I then have a derived class that also has a CSLA property with a [Required] data annotation attribute.
When I try to instantiate the derived class, it fails with a System.TypeInitializationException : Can not register property x after containing type (y) has been instantiated.
When I trace into the CSLA code, the BusinessBase processes the DataAnnotation on the derived class; when it hits the forceInit in the base constructor, the error occurs.
I have attached a sample application with CSLA 4, .NET 4 and Silverlight 4 that reproduces this issue.
Any help would be appreciated!
Mark
Stack trace from my attached sample application :
{System.TypeInitializationException: The type initializer for 'Csla4Troubleshoot.Troubleshoot.MyBaseClass`1' threw an exception. ---> System.InvalidOperationException: Can not register property Id after containing type (Employee) has been instantiated
at Csla.Core.FieldManager.PropertyInfoManager.RegisterProperty[T](Type objectType, PropertyInfo`1 info)
at Csla.BusinessBase`1.RegisterProperty[P](PropertyInfo`1 info)
at Csla.BusinessBase`1.RegisterProperty[P](Expression`1 propertyLambdaExpression)
at Csla4Troubleshoot.Troubleshoot.MyBaseClass`1..cctor()
--- End of inner exception stack trace ---
at Csla4Troubleshoot.Troubleshoot.MyBaseClass`1..ctor()
at Csla4Troubleshoot.Troubleshoot.Employee..ctor()
at Csla4Troubleshoot.App.Application_Startup(Object sender, StartupEventArgs e)
at MS.Internal.CoreInvokeHandler.InvokeEventHandler(Int32 typeIndex, Delegate handlerDelegate, Object sender, Object args)
at MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, String eventName)}
To respond to my own question : I removed the forceInit from the base class and simply made my PropertyInfo<T> declarations public (as prescribed by this thread - http://forums.lhotka.net/forums/p/7986/38220.aspx#38220). This eliminated the initialization issue I was encountering.
I am trying to use a custom identity derived from Csla.Security.CslaIdentity. For now I am just adding an extra test property that is public static and I still get the error about "Can not register propery ExtraString after container type (CslaIdentity) has been instantiated at ....".
Can you see anything wrong with this class?
namespace Profiler.Lib
{
[Serializable()]
public class UsiIdentity : Csla.Security.CslaIdentity // Csla.Silverlight.Security.WindowsIdentity
{
public UsiIdentity() { }
public static PropertyInfo<string> ExtraStringProperty = RegisterProperty<string>(new PropertyInfo<string>("ExtraString", "Extra String Test Property", string.Empty));
public string ExtraString
{
get { return GetProperty(ExtraStringProperty); }
}
Please ignore. I found another forum post that explained the problem is because CslaIdentity is not a generic and therefore you have to use long form of RegisterProperty() like this:
public static PropertyInfo<string> ExtraStringProperty = RegisterProperty(typeof(UsiIdentity), new PropertyInfo<string>("ExtraString", "Extra String Test Property"));
Copyright (c) Marimer LLC