Enjoying the flexibility of DI and IoC

Some post header data
Enjoying the flexibility of DI and IoC
4/25/2013 6:30:11 PM

I am trying my best to get back into blogging.  After having moved to Texas and starting my own ranch/farm…I have had difficulties staying focused on technology when I am not work.  For that reason I will try to do quick posts while at work…while I am focused on technology.

To start this quick story I have to first mention that we have released several iterations of our product “Marketvine Picks” where Marketvine is the company we are spinning out of Dell as and Picks is the social commerce-y product we have created.  Currently you can see this product on www.citysports.com, www.eyeslipsface.com, and as of last night on www.surlatable.com.

If you aren’t close to me and my work world you would be interested in knowing that our application is running on .net and javascript in the Amazon cloud.  Thank god for the Amazon cloud!  With each new release we take a substantial amount of additional traffic.  With each new set of traffic we encounter interesting scaling issues.  We have done the normal query tuning and coding optimizations and have enjoyed the dynamic scaling abilities of our infrastructure that AWS gives us.  But in preparation for future releases where we might anticipate some bottle necks at the database we have preemptively decided to get ready for separating our reads and writes.

Using read replicas from an infrastructure point of view is not always easy.  However, we are in AWS…so this feature is as easy as adding a new read replica.  Right click on an RDS instance and add a read replica.  Quick modal configuration.  GO…minutes later we have a read replica.

Depending on how you chose to structure your application you may or may not be ready to utilize this easy to use feature for horizontal scaling.  Going wide with your database if you will…rather than standing up a more powerful database server.  You can have up to 5 read replicas per each master instance.  NICE!

In our case we made an decision early on to at least contain our read queries and our write queries in separate containers.  We pretty successfully conform to the concept of command query separation (CQS).  This allowed us to easily tackle the concept of a read connection string and a write connection string later on.

Well…later on is here now!

We now have two separate connection handlers 1) MySQLReadonlyDatabaseFactory and 2) MySQLReadWriteDatabaseFactory.  But how to get this new concept into our code?  Thank god for IoC (Ninject in our case).

We have marker interfaces on all the classes that do reads vs. writes.  If the class does solely reads they are marked with IQueries.  If they do solely writes then they are marked with ICommander.  This has then allowed us to swap in our new functionality with just a few lines of IoC configuration code:

   1:  _kernel.Bind<IDatabaseFactory>().To<MySQLReadonlyDatabaseFactory>()
   2:      .WhenInjectedInto<IQueries>();
   3:  _kernel.Bind<IDatabaseFactory>().To<MySQLReadWriteDatabaseFactory>()
   4:      .WhenInjectedInto<ICommander>();
   5:  _kernel.Bind<IDatabaseFactory>().To<MySQLReadWriteDatabaseFactory>();
The first 2 lines of configuration wire in a read only db factory for classes with a marker of IQueries.  The next 2 lines wire up a read write compatible connection for classes with the market of ICommander.  And to provide a default behavior we wire in the read write where a database factory is required without any additional marker information. 
With that change in place you are able to have two connection strings.  One connection string points at the master MySql instance.  The read only connection string can point at all the read replicas in the environment.  This then means that we can run many more much smaller (and therefore cheaper) database instances.
comments powered by Disqus