Geeks With Blogs
On the Ledge The general evolution (and occasional regression) of a .NET developer

All right, so it may have been a day or two since my last post.

I was hoping I'd have the option to post-date to make it look like I was a much more diligent blogger than I really am, but oh well.

Apart from just wanting to look like I blog more regularly than once a quarter, there's actually a lot of material to cover.  I'm not sure exactly how I want to accomplish this, so there might be a spate of blogs close together just to cover all the things I've worked on so far and the challenges involved.  Before getting into specific tasks, though, you really ought to know a little bit about the architecture and the systems that I work with.  This will probably be a longish post.  Sorry about that.

They say that Alexander the Great designed the city of Alexandria around the idea of the human body - the centers of government, the transits, the various areas of functionality were all arranged according to the human body, thus creating something of a "living" system.

The code base I work with is similar.  It is extremely object-oriented, and each object has a very fine layer of granularity.  Systems work primarily through several objects working together to complete a task as opposed to a large object responsible for an entire task (although, it's not uncommon to have objects that monitor a task's progress and do different things based on timeouts, exceptions, logging, etc.).  There are several systems that work together to represent the entirety of the process our software does, including some interaction with third-party systems.

At the core of everything is the Framework, but I can't keep calling it the Framework because we typically mean the .NET Framework when we say that.  In order to avoid any semblance of giving out proprietary information unintentionally, I'm going to call it the Q Framework, after this dapper-looking gentleman from Star Trek: The Next Generation.  I always thought Whoopi Goldberg's character might also be a Q, but I digress.

The Q Framework consists of 38 Visual Studio projects that run the gamut from O/RM to UI generation to JavaScript generation to database access to MVC to reporting to content management.  Appropriate DLLs from the Q Framework are used in all the other Solutions we create, which are currently several client websites, a few intranet/administration websites, a desktop client, a content-management platform, and different services both web and Windows.  Virtually all of this has been written in-house with most third party libraries being used for template generation and unit-testing.

The code uses metadata extensively, and the preferred method of writing this metadata is to decorate the code with custom attributes.  Depending on the code, this metadata is used in many different ways, including instantiating objects in memory that represent the metadata and using CodeDom to actually generate concrete classes based on decorated Interfaces (it writes .cs files, saves them to the hard drive, and compiles them when the application is initialized at startup).  There's a sense in which parts of the application basically write themselves, which is an equal combination of eerie and cool.

For example, it's a relatively common pattern in our code to have a class - let's say Foo - and also have a FooDescriptor.  The FooDescriptor is a class that represents in-memory all the metadata that decorates a Foo object (needless to say, all Foos implement the IFoo interface).  In the MVC portion of the Q Framework (which I and our Architect wrote, together), you have an IController interface.  All classes that implement this interface (i.e. all controllers) will decorate themselves with an attribute that has the URL pattern they respond to.  Each controller method is decorated with an attribute that has the command (from the URL) that runs that method as well as the preferred View to use.

At runtime, the application, on startup, creates a static instance of a context that stores a collection of controllers in whatever the app is as well as a collection of descriptors of each controller, and these objects work together to execute controller code appropriately.

You might be asking at this point - why use attributes for that?  Why not actually code that information into the classes and methods of the controller?  Well, one thing, this makes it a little easier to have multiple "controllers" respond to requests.  Going into how we use that is probably best saved for another post, but the upshot is that it allows us to have finely-grained controllers with specific purposes that work together in a chain to appropriately handle a request.  Another thing is this allows classes to supply data that doesn't really fit nicely into code.  For example, an attribute on a ViewData object states what web UI control it prefers to be rendered as.  This is nice to pull from a lightweight attribute in a generic fashion as opposed to storing it in a property or some other mechanism.

The other thing it allows us to do, however, is to allow us to work without concrete implementations until runtime.

The way our O/RM works, the actual data transfer classes are all Interfaces - there's not a single bit of code in them.  They all, however, have metadata that maps each Interface and property to database tables and fields.  When the app is initialized at startup, the Q Framework uses CodeDom to create concrete implementations of these classes, saves, and compiles them for the application's use.  When you combine these with the attributes that link this data to Views (and we have several intermediary classes to make this possible), you can literally create an Interface that represents your data, decorate it appropriately, and the application itself will write these objects into the database, generate the CRUD operations, generate a web form with JavaScript validation, and generate reporting.  All our reports, by the way, are also decorated Interfaces, which allows the construction of new reports in a very short amount of time - just write your Interface, decorate it with the appropriate metadata, and the application will generate the report.

There are many ways to skin a cat, and I'm not saying this setup is the absolute best that could possibly be conceived, but it's extremely slick, and the benefits are that new development happens very rapidly (unless you're me and aren't used to coding in this way) and, because of the granularity and isolation of each class, it's very rare that two developers actually work on the same code at the same time, or even follow up on someone else's code to modify or add to it (with the exception of bug fixes).

Anyway, armed with this overview of how things were designed, that should help a little when I start talking about specific projects.  Other than bug fixes, my two, main projects have been writing a Proxy service and co-writing the MVC Framework portion of the Q Framework.  More on these in other posts.

Posted on Tuesday, September 15, 2009 9:58 AM Architecture | Back to top

Comments on this post: Alexander the Great and Systems Architecture

No comments posted yet.
Your comment:
 (will show your gravatar)

Copyright © ledge | Powered by: