Check out the Latest Articles:
My Application Framework

Going to try and keep this one short as I don’t want to bore anyone!

About six months ago now I began attempting to create my own framework of systems that I could use when building websites. My vision was to have a core set of libraries that could be used across any system for example I have Generic Repositories which allow data access for any entity that implements my IBusinessObject interface. I also have a set of Generic Service classes for my Business Objects which in time will hopefully act as a Caching layer when I get time to write a Memcached implementation. I also wanted to have a User, Logging and Email system which could also be used by any application and which would use my core libraries.

Anyway I began creating this in a traditional way having a relational database etc etc, but then I got a new job with Illy Systems and met some extremely intelligent developers. This lead me to rethink my Framework and I began to work in a new way.

The guys at work had just started using nServiceBus in a “Pluggable” way. I found this really interesting and whilst they use monorail for their website frontend. I wanted to create a way to do it with ASP MVC.

So this is how I’ve done it. When the Web / Service Bus applications start up they scan a certain directory for assemblies. In the Web project it is {WebDir}/Plugins in the service bus this is located in the bin/Plugins. It loads all of these assemblies into a dictionary. Once complete the application executes a series of startup tasks starting with scanning all of the assemblies in the dictionary for Windsor Installers. I have two types of installers a IWebInstaller and IBusInstaller and you set the context upon calling the Bootstrapper in the Global.asax. This then installs everything you tell it to into the Windsor Container from the plugin assemblies.

This includes all Repositories, Services, Validations, Configuration, Controllers, Razor Views where I have used David Ebbo’s Razor Generator to compile them, and then two interfaces I have created call IRegisterRoutes and IRegisterNavigation (We shall get to these in a bit).

  • It then adds a new method to the app domain assembly resolve event handler which exists in the class which contains the dictionary of assemblies. Now when the application needs an assembly it will check the dictionary as well as the bin folder/gac.
  • It then starts nServiceBus and registers it into the Windsor Container.
  • It then overrides the View Engine with one that looks in the Windsor Container for the page instead of on the file system.
  • It then overrides the Model Validation and uses the Fluent Validation framework instead.
  • It then initialises Logging using a Global Filter which will send a Message to the Logging queue for the logging service host to handle whenever there is an unhandled exception.
  • It then Resolves all of the IRegisterRoutes from the container and adds them to the Routes Table. I thought this could be a good idea for developing in a plugin / soa way as each of your components can consume other components and using routes can mask the actual implementation of these controllers, making it easier to swap in and out new plugins when needed. However I have only managed to get this to work when a request comes in from a browser. When I use ActionResult which I believe creates a new request but only in an internal way it doesn’t seem to use the routing engine (Help with this bit would be appreciated!)
  • It then also resolves all of the IRegisterNavigation implementations and builds an overall Navigation structure from them which is then registered into the container.
  • Finally it overrides the Controller Factory with one that resolves the controllers from Windsor.

The application is being created in a way where you have Services which are made up of Autonomous Components which act independently of each but which share a set of messages in order to maintain their own datasets and perform what they need to do depending on the events which have happened in the system. Some of these messages inherit from an external source of messages which is information which is deemed to be ok to share with other services. These could be services you build or services someone else has built who doesn’t even know you. This makes it necessary to think about what you are exposing to the external world.

Basically in a normal process this is what happens. User performs an action using an interface. This gets mapped to a controller action which then populates a pre command. The pre command populates an object and validates it. If the object is not valid the controller returns the Validation Results from the pre command and validation messages are shown for the user to try again. On a valid attempt the pre command then sends a message on to the Bus and releases the request. The message sent is generally a command message which is handled by one backend message handler. The handler validates the process again and ensures its still ok to complete this action. If it isn’t it throws an exception, if it is it persists the action and then publishes an event message. It’s this event message that other components listen to. As the internal messages inherit from the external messages. Other messages in the same service can get the extra information exposed to them and external components still receive the messages with less information exposed to them. These handlers then perform whatever they need to do.

Once complete the front end is now up to date with the backend but the user hasn’t had to wait for the process to complete.

The reason for developing in this way is to create a system that can easily be distributed and hence allow it to scale (This is perhaps for another article or your own reading).

Obviously the user is going to experience an out of sync system. However I have a few ideas on how caching could be used to “fake” their actions and make it appear to be completed when the backend hasn’t actually processed it yet.

Anyway the framework is far from complete and apologies for a scattered article. I just wanted to get what I had been playing with out there and perhaps get interest from others on helping with it.

If you are interested in helping with this perhaps comment on this article or contact me on github the repository is located here, and I will get back to you!

Cheers,
Jon



  1. It‘s quite in here! Why not leave a response?