The application I've been working on for the past couple of months has a very generic UI on it. It uses a database table which configures which tables a user can see, how they see them, and what data they contain. This is all based on the entities that are available to the system through the LLBL generated data layer. Basically anything in the DAL can be configured, and anything that is configured can be modified by the user.
The UI literally consists of 1 form and 2 web controls, which configure themselves to suit whatever entity we are working with at the time. While this is all working fairly well at this point, some of the code that we needed was a little different. We are using reflection in lots of places to access properties on objects because we can't tell at design time which type of object we will be working with. LLBL defines a bunch of interfaces for their entities and collections which made this all possible. But one thing caused me some grief.
When we first load the form we need to get a list from the table based on some criteria and display all of the applicable records. Again, at design time we didn't know what type of collection we would need, so we couldn't use
Dim c As new LWS_DAL.CollectionClasses.ClientCollection
for instance. We instead had to use
Dim c As ORMSupportClasses.IEntityCollection = new LWS_DAL.CollectionClasses.ClientCollection
But how to load a collection at runtime when you know the name of it, but not the type? LLBL provided a factory that would return a collection of the correct type if you already had an entity, and the collection would return an entity of the correct type, but getting in the door the first time was a pain.
At first we had a long Case statement which would accept the entity name as a string and return the new collection, but it was a pain to maintain, and was not my intention to keep anyway, it was just all that I had at the time. We replaced it with this:
Public Shared Function GetCollectionByName(ByVal EntityName As String) As Object
Dim retval As Object = Nothing
'Get the assembly that is loaded that contains the type of AddressBookCollection (the DAL).
'Doesn't matter what type we use, as long as it is in the LWS_DAL namespace
Dim a As System.Reflection.Assembly = _
System.Reflection.Assembly.GetAssembly( _
GetType(LWS_DAL.CollectionClasses.AddressBookCollection))
'Convert the entity name into the complete name of a collection of the appropriate type
Dim FullName As String = "LWS_DAL.CollectionClasses." & EntityName & "Collection"
'Use the referenced assembly to get the specified collection
retval = a.CreateInstance(FullName, True)
'Return the object.
Return retval
End Function
This code gets the assembly that contains a well-known type at design time. Which well-known type isn't important, as long as we know that it is in the DAL assembly. Because this assembly is already loaded by the application when it starts up, we can find the assembly from any of the types in it. Once we have the assembly we build a string that contains the complete name of the object we are looking for, and then tell the assembly to give us one of those. If you wanted you can also load the assembly directly from the path, but they you'd need to know where it was.
Reflection is one of those things that made .NET famous, and in my experience very few people actually have ever needed to use. This project is the first one that I've used a lot of reflection in. Most of the time it's just not necessary, you always know the types you are working with when you build the page or control.