We have a very generic hierarchy structure that we've defined. The database consists of Hierarchy, HierarchyNode. I've got CSLA objects generated against those tables.
Now, what we want is the ability to do Hierarchy<Merchant> myMerchantHierarchy but this isn't something the CodeSmith templates will allow.
My next proposition was
public class GenericHierarchy<T> : Hierarchy
However, this won't work either because Hierarchy, being CSLA is created with factory methods and don't expose a constructor.
What I currently have is
GenericHierarchy<T>
{
public Hierarchy _internalHierarchy;
}
Along with some functions that facilitate the ability to get the data from a node by instantiating an instance of T and calling the LoadData function passing it the dataKey of whatever the current HierarchyNode is.
The problem with this approach is that it forces T to be of a certain type. It can't be an interface because you can't declare instances of an interface.
The solution works except that all of my T objects must now inherit from my AbstractHierarchyNodeData object which means they can no longer inherit from anything else (something a lot of our ojects, like Merchant, already do).
In order to then get a Hierarchy of Merchants we'd have to build a Merchant wrapper that inherits from AbstractHierarchyNodeData.
Also, all of that work and I still can't treat my GenericHierarchy as an actual hierarchy, since it's nothing more than a wrapper around a hierarchy object. Subtle but important difference there.
Any ideas?
Thanks,
Will
Ok, I did end up writing a workable solution for this. The end result is you can create an instance of T where T implements some interface.
You just can't do new T() without adding new() to the specification of the generic parameter or you can use Activator.CreateInstance(typeof(T)).
However, my supervisor still wants me to do this
public class Hierarchy : BusinessBase
public class GenericHierarchy<T> : Hierarchy
Inheriting directly from CSLA objects won't work because CSLA goes through the factory methods and don't expose a public constructor (at least not a usable one from the code generator). What would we have to do in order to expose the public constructor for our Hierarchy object and not run into any problems with how the DataPortal does its work?
He's thinking that just dropping this code into the constructor would work.
return DataPortal.Fetch< Hierarchy >(new HierarchyCriteria(requiredParameters));
Obviously, this won't work, but there has to be a way to accomplish the same chore in the constructor that doesn't take everything away from how CSLA works.
Thanks,
Will
Because Hierarchy is a CSLA object generated with CodeSmith. Making it generic would require that I edit all of the generated code as well which was not a direction we wanted to go with, although it would make the most readible and logical code...
Will
That's purely a matter of the development effort involved. I'd have to write a template (set of templates) that generate a CSLA object that is generic. All the development and testing involved in that would put me way past my deadline. It would also mean having to keep up with even more differences between the Codesmith.CSLA templates and our custom templates.
Will
Copyright (c) Marimer LLC