Design Patterns
Auto-Creating Your DB with Active Record
Jul 13th
During some recent development the team I was experiencing some friction with databases and developing. We were using Castle Active Record and we soon realized that as new people joined the team, left the team (rinse, wash, repeat), db changes occurred in the Active Record Schema etc, that the set up time to going was miserable.
The problem at the time is that you’d have to set up the DB in SQL Express (which is what we used during development), make sure the schema was correct, make sure you had the most recent baseline,change scripts, etc. We were not following a db change management workflow as in regards to version control as we were using Active Record (all schema is based off of the objects) and we were developing a new product from the ground up. Therefore once we were done we could auto-gen the scripts and go from there. At that point we could implement a version control process for our db.
To make a long story short … we wanted to be able to check in active record changes, and make updating the database as easy as visiting a route on the ASP.NET MVC Application. This route would update the database schema and update the tables, etc. The issue is that if the database was never created in the App_Data directory (we did not check in the .mdf into version control) then we would have a problem. We needed to create one on the fly.
How
Here’s how to create a database on the fly with a few simple SQL commands. Here is an example:
public void CreateDatabase(string filename)
{
string databaseName = System.IO.Path.GetFileNameWithoutExtension(filename);
using (var connection = new SqlConnection(
@"Data Source=.\SQLEXPRESS;Initial Catalog=tempdb;Integrated Security=true;User Instance=True;"))
{
connection.Open();
using (var command = connection.CreateCommand())
{
command.CommandText =
"CREATE DATABASE " + databaseName +
" ON PRIMARY (NAME=" + databaseName +
", FILENAME='" + filename + "')";
command.ExecuteNonQuery();
command.CommandText =
"EXEC sp_detach_db '" + databaseName + "', 'true'";
command.ExecuteNonQuery();
}
}
}
What we’re doing here is creating a database via file name and then disconnecting the database from the server. This leaves us with an mdf file sitting on the disk somewhere.
The ‘filename’ attribute specifies where the file (example.mdf) should go. This is obtained by executing the following code:
string dataDirectory = Convert.ToString(AppDomain.CurrentDomain.GetData("DataDirectory"));
string mdfPath = Path.Combine(dataDirectory, "admin.mdf");
After we create the database we need to create the schema’s. Here’s the call to do this:
public void CreateSchema(string path, string schema)
{
var connectionString =
String.Format(
@"Data Source=.\SQLEXPRESS;AttachDbFileName={0};Integrated Security=True;User Instance=True;", path);
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
using (var command = connection.CreateCommand())
{
command.CommandText = String.Format("CREATE SCHEMA [{0}]", schema);
command.ExecuteNonQuery();
}
}
}
With the call above we have attached to the db using SQLExpress and created a schema through the CREATE SCHEMA call. We would call this method for each schema we had like this:
// Get your mdf path as shown above localDbManager.CreateSchema(mdfPath, "Customers"); localDbManager.CreateSchema(mdfPath, "Shipping"); localDbManager.CreateSchema(mdfPath, "Logistics"); // ... etc, etc, etc ...
Remember, this may look expensive in regards to setting up a db, but this is only called when the user requests it, OR, if set up to do so, such as at the time of initialization of the application (which is where I put this code – this allows the dev who is opening the app for the first time to get the latest and greatest in regards to the db set up when he/she starts the app).
Finally, we call:
ActiveRecordStarter.UpdateSchema();
This tells ActiveRecord To generate the scripts and run them against the current db.
At this point you would have a db up and running within your App_Data directory.
I have purposely left out a lot of details of how the app sets itself up, so I have included a sample app you can download and run. All of the assemblies are included. Download, open the sln, and run. As long as you have access to write a file to the file system, this will work.
Download Sample
The sample is a ASP.NET MVC application with the Spark View Engine. Other technologies used in the sample: Windsor Container, Castle Active Record
Important Notes: The Windsor.config file contains the ActiveRecord connection information. We use Windsor Container to inject and resolve instances in the controllers and other areas of the app. The app will attempt to create and update the db upon application start (global.asax) and you can force a schema update through the /admin/updateschema/ route.
![]()
Download Zipped Solution (5.3 MB)
Running the Sample
Running the sample is fairly straightforward. When the app starts you will be presented with this screen:
If you look in your App_Data directory you will see your admin.mdf file inside of the directory as such:
If you were to attach this to SQL Express Management Studio and looked at the DB, you would see the tables, etc.
To load data into the db for the sample, I have created a simple route that creates a random customer and loads it into the database. Click the link “Create Random Customer” and a random customer will be created. You can then click on the customer to view details about the customer or you can delete the customer by clicking on the “x”. Its a very rudimentary example, but it provides all of the end to end goop for you to grok this example.
Conclusion
By no means is this a replacement for your production DB. You’d never want to auto-gen your DB (unless it always started out empty, etc). This is the perfect scenario for an agile project where changes are made frequently and keeping db changes up to date across a developer team is a difficult task.
What about pre-loaded data for look up tables, etc?
This is a fairly simple problem to fix. I have created a property that is injected via setter injection into the Application.cs file. The property is “ShouldInitializeData”. If true (set this in the /config/WIndsor.config) the application will initialize some data with the DataInitializationService. Inside of this service you could call a handful of other services to initialize data, or you could perform the initialization inside of this service itself. Its up to you at this point. I have included this as part of the sample.
Enjoy.
ASP.NET MVC – Windsor Container Controller Factory
Jul 10th
Here is a simple class that allows you to use a container to register and resolve your instances of controllers. You’d want to do this if you inject dependencies into your controller via constructor injection.
Controller Example:
public class AdminController : Controller
{
private readonly ILocalDbManager _localDbManager;
public AdminController(ILocalDbManager localDbManager)
{
_localDbManager = localDbManager;
}
public ActionResult Index()
{
return View();
}
// Other Actions ...
}
If you use the default ControllerFactory provided by ASP.NET MVC you’ll get a MissingMethodException, such as this:
No parameterless constructor defined for this object.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.MissingMethodException: No parameterless constructor defined for this object.
The default ASP.NET MVC Controller Factory looks for a parameter-less constructor to build the controller from. If it cannot find one, the above is what happens.
Since I want to use a container (Windsor in this case) to supply my depenencies, the default ControllerFactory will not work. We have to create our own.
The Container Controller Factory
Building your own controller factory is easy. Simply implement the IControllerFactory interface from the System.Web.Mvc namespace and then set your controller factory as the one to use. Here’s how to do it:
The Controller Factory
public class ControllerFactory : IControllerFactory
{
private readonly IKernel _kernel;
public ControllerFactory(IKernel kernel)
{
_kernel = kernel;
}
public IController CreateController(RequestContext requestContext, string controllerName)
{
return _kernel.Resolve<IController>(controllerName.ToLowerInvariant() + "controller");
}
public void ReleaseController(IController controller)
{
_kernel.ReleaseComponent(controller);
}
}
This class, takes a container in through the constructor, and then resolves a controller from the container via the name of the controller . It then releases it from the container when its done with it.
Please note, you can create your own naming structure when you register your controllers, and if you do so you’ll need to adjust the “CreateController” method to resolve to the proper key in the container.
Now that we have our own ControllerFactory, we need to put it INTO the container so we can have the kernel injected via the constructor.
This is a bit difficult to understand, therefore I’m going to post the code and then explain it.
Global.asax.cs
public class Global : System.Web.HttpApplication
{
public static WindsorContainer container;
protected void Application_Start(object sender, EventArgs e)
{
container = new WindsorContainer(Server.MapPath("~/Config/Windsor.config"));
var app = container.Resolve<Application>();
app.RegisterFacilities(container.Kernel);
app.RegisterComponents(container.Kernel);
app.RegisterRoutes(RouteTable.Routes);
app.RegisterViewEngines(ViewEngines.Engines);
// Tell MVC which controller factory to use. Since we're using
// the container to inject some items into the controller we need to use this controller factory
// that was set up in the component registration.
ControllerBuilder.Current.SetControllerFactory(container.Resolve<IControllerFactory>());
}
// Other global members below ...
}
Application.cs
public class Application
{
public void RegisterViewEngines(ViewEngineCollection engines)
{
if (engines == null) throw new ArgumentNullException("engines");
SparkEngineStarter.RegisterViewEngine(engines);
}
public void RegisterRoutes(RouteCollection routes)
{
if (routes == null) throw new ArgumentNullException("routes");
// default route
routes.Add(new Route(
"{controller}/{action}/{id}",
new RouteValueDictionary(new
{
controller = "home",
action = "index",
id = ""
}),
new MvcRouteHandler()));
}
public void RegisterComponents(IKernel kernel)
{
kernel.Register(
Component
.For<IControllerFactory>()
.ImplementedBy<ControllerFactory>(),
// Register all controllers in assembly.
AllTypes
.Of<IController>()
.FromAssembly(typeof (Application).Assembly)
.Configure(
reg =>
reg.Named(reg.Implementation.Name.ToLowerInvariant()).LifeStyle.Transient),
// Register all services that implement marker interface in current assembly
AllTypes.
Of<IService>()
.FromAssembly(typeof (Application).Assembly)
.WithService.FromInterface());
}
public void RegisterFacilities(IKernel kernel)
{
kernel.AddFacility("logging", new LoggingFacility(LoggerImplementation.Trace));
kernel.AddFacility("activerecord", new ActiveRecordFacility());
}
}
This is done in the Application.cs file (which is the bootstrapper for the container and other application details). This class is called on Application Start. We call a RegisterComponents on the Application.cs file and give it a container in which to register things.
In the RegisterComponents method call we register the ControllerFactory in the container, and then all of the other components. A key one to notice is this bit of code:
// Register all controllers in assembly.
AllTypes
.Of<IController>()
.FromAssembly(typeof (Application).Assembly)
.Configure(
reg =>
reg.Named(reg.Implementation.Name.ToLowerInvariant()).LifeStyle.Transient),
The code above analyzes the current assembly (which Application.cs resides within), and configures the container to load all instances of IController (which is implemented on the Controller base class in ASP.NET MVC). In short, it registers all controllers into the container. The dependency is registered with a key, that is the name of the controller. Therefore if you have a controller called “AdminController” the key would be “admincontroller”. We then set the life style to transient for each controller.
This naming structure has meaning. If we look at the ControllerFactory again below …
return _kernel.Resolve(controllerName.ToLowerInvariant() + "controller");
… we can see that when we resolve the controller from the container we use a string key and concatinate the “controller” to the end of it. This is the key in the container. At this point the proper controller will be returned. If you change yoru controller key structure you will need to change it in the registration as well as in the factory (as they depend on each other).
In the Global.asax.cs file we are setting up a new container, and upon Application Start we register the components, facilities, view engines, and a few other things (which the component registration is shown above). At the bottom of the Application_Start call, we tell the ControllerBuilder class (which is in the System.Web.Mvc namespace) to set the ControllerFactory to our own ControllerFactory … like this:
// Tell MVC which controller factory to use. Since we're using // the container to inject some items into the controller we need to use this controller factory // that was set up in the component registration. ControllerBuilder.Current.SetControllerFactory(container.Resolve<IControllerFactory>());
All Done
Now, when we fire up the app, the following will happen:
- The App Starts
- The Container is created
- The Container registers its components
- The controller factory gets registered, its dependency, IKernel, is injected from the kernel itself (it knows how to supply itself to an object if it needs it)
- The controllers get registered with key.
- Our new ControllerFactory is set to be the ControllerFactory to use when resolving controllers during runtime via the SetControllerFactory method.
- When a route is requested, our ControllerFactory will take over, the controller will be resolved via the key that is created by using the name of the current controller concatenated with the word “controller” (following a convention over configuration methodology).
- The controller is returned with all of its dependencies resolved, which in this case would be ILocalDbManager
- The app then continues to run.
At this point your able to create a controller which takes injected dependencies. This helps with decoupling, maintenance and also testing.
Auditing with Castle Active Record
Jun 9th
Sometimes you need to audit everything you do in a transactional system. A lot of standards such as SOX and others state that you must audit your transactions. Doing this by hand inside of your system can (and usually is) a huge PITA. However, it is a necessary evil in some instances.
However, if you’re using Castle’s Active Record (AR) for your database access, then hopefully this post will save you some trouble.
Active Record provides us with the ability to provide interceptors which “intercept” the execution of some of the Active Record calls. I’m using the ActiveRecordMediator<T> class for all of my CRUD operations and in order to implement some sort of auditing I need to be able to intercept all of my Save, Updates and deletes. Here’s the class that does this:
The Interceptor
using System;
using System.Collections.Generic;
using Castle.ActiveRecord.Framework.Internal;
using NHibernate;
using NHibernate.Type;
namespace Felker.AR.Audit
{
public class AuditInterceptor : EmptyInterceptor
{
private static AuditInterceptor instance = new AuditInterceptor();
protected AuditInterceptor() { }
public static AuditInterceptor Instance
{
get { return instance; }
set { instance = value; }
}
public override bool OnFlushDirty(object entity, object id, object[] currentState, object[] previousState, string[] propertyNames, IType[] types)
{
// Object was updated. Save the current state, previous state, etc.
return false;
}
public override void OnDelete(object entity, object id, object[] state, string[] propertyNames, IType[] types)
{
// Object was deleted.
}
public override bool OnSave(object entity, object id, object[] state, string[] propertyNames, IType[] types)
{
// Object was created. "state" is the state of the object.
return false;
}
}
}
The class above implements a default “EmptyInterceptor”. This allows you to override the methods you need in your interceptor. I have overridden the “OnSave”, “OnDelete”, and “OnFlushDirty” methods. When the interceptor is in place, when a Save, Delete or Update call is made with the ActiveRecordMediator<T> the respective overrides will get called.
It is inside of the “OnSave”, “OnDelete”, and “OnFlushDirty” that I can perform my auditing as I am provided with the object state during the save, delete or update. I have not provided any sort of mechanism in the code to actually audit the info to a database or a file as this is up to you to decide “where” it should go. This is only the boiler plate that you can use to intercept the save calls. You have all the data you need. The current entity, the current state (and previous state if it is an update) and the type information.
Why Works So Well
The beauty in this implementation is that I _did_not_ have to change _any_ of my pre-exising ActiveRecordMediator<T> code. I had a TON of models that used a common repository and I did not have to tough them. I just had to add the interceptor to the container (Windsor Container) at app startup and ActiveRecord picked up the interceptor and started firing it.
Wiring up the Interceptor with a Facility
using Castle.ActiveRecord.Framework;
using Castle.Core.Configuration;
using Castle.MicroKernel;
using NHibernate;
namespace Felker.Castle.Facilities
{
///
/// Allows for the system to pick up the audit facility which will be used to
/// audit all transactions in the system.
///
public class AuditFacility : IFacility
{
#region IFacility Members
public void Init(IKernel kernel, IConfiguration facilityConfig)
{
InterceptorFactory.Create = new InterceptorFactory.CreateInterceptor(CreateAuditInterceptor);
}
public void Terminate()
{
// Nothing to terminate
}
#endregion
private IInterceptor CreateAuditInterceptor()
{
return AuditInterceptor.Instance;
}
}
}
The class above creates a Facility for Active Record. We wire this up in the Global.asax.cs file like so:
static private IWindsorContainer _container;
protected void Application_Start(object sender, EventArgs e)
{
try
{
_container = new WindsorContainer(Server.MapPath("~/config/windsor.config"));
var app = _container.Resolve();
app.RegisterFacilities(_container);
app.RegisterComponents(_container);
}
}
In the Application.cs file we add the facility as such:
public void RegisterFacilities(IWindsorContainer container)
{
container.AddFacility("audit.support", new AuditFacility());
}
The code above wires up the facility into the container which will handle all of our type registration/etc for us.
Conclusion
The container now contains the facility which will wire up the audit interceptor which will intercept all ActiveRecordMediator<T> calls.
We have not changed a line of code in our existing system, yet we have added the ability to audit all of our CRUD operations in a simple yet effective manner.
Castle Windsor 2.0 RTM
May 6th
2.0 RELEASED!
Wow… I’ve been using castle for, I’m not sure, maybe 4 years and its finally released version 2.0. I’ve been running off the trunk for _ages_ too. I’m happy to see that this new version of Castle Windsor has been released.
Get the bits here.
Featured in the Spaghetti Code Podcast
Apr 7th
I was recently interviewed on the Spaghetti Code Podcast, hosted by Microsoft’s Jeff Brand.
Jeff and I talked about Mocking and how it relates to the development process, testing process and your day to day coding.
You can download the files from the SlickThought website here or from ITunes here.
* I’m not sure if ITunes has updated yet, but it should be up there soon.