We are in the process of migrating CSLA from 1.3.0 to 3.8.2. We have some issues with generics and the UI and we would like to know if somebody has a solution.
We have a control base class (RootEntityControlBase) that has property of type BusinessBase. All the entity controls that require a business object inherit from RootEntityControlBase. Since now the BusinessBase class is generic we found some challenges. (1) We cannot have the property of a generic type without knowing the actual type. To fix that we made the control itself be generic, which actually sounds like the right way to do it (we can use the type in methods and events as well). (2) Since the control base class is generic the designer is not able to render this form giving us the following exception:
The designer could not be shown for this file because none of the classes within it can be designed. The designer inspected the following classes in the file: LoanSetupEntityControl --- The base class 'RootEntityControlBase' could not be loaded. Ensure the assembly has been referenced and that all projects have been built.
What is the best way to have a generic BusinessBase reference or property in windows base controls and still be able to edit UI in visual studio designer?
Example of what we have:
public class UserControlBase : System.Windows.Forms.UserControl
public class RootEntityControlBase : UserControlBase
{
[DefaultValue(null)]
public virtual BusinessBase EntityReference
{
get
{
if(IsDesignMode(this)) return null;
throw new Exception("EntityReference property must be implanted.. ");
}
}
}
public class LoanSetupEntityControl : RootEntityControlBase
Example of what we changed it to, but UI cannot render:
public class UserControlBase : System.Windows.Forms.UserControl
public class RootEntityControlBase<T> : UserControlBase
where T : BusinessBase<T>
{
[DefaultValue(null)]
public virtual T EntityReference
{
get
{
if(IsDesignMode(this)) return null;
throw new Exception("EntityReference property must be implanted.. ");
}
}
}
public class LoanSetupEntityControl : RootEntityControlBase<LoanSetup>
Windows Forms is not friendly to generics, so you really need to keep the UI generic-free.
Generic types are not polymorphic - you need a non-generic base type or interface if you want to write code that can interact with any Blah<T>.
CSLA exposes (in Csla.Core) a set of interfaces to make it relatively easy to create a UI framework that works regardless of the actual business object type. If you have extra properties or behaviors common to all your business objects, I suggest you follow the same approach - define a non-generic interface and implement it in your custom base class.
Copyright (c) Marimer LLC