Lately I have been tasked with fixing a couple projects for clients where they were experiencing sporadic and unexplainable errors. In both cases, I was shocked that previous developers had not taken the time and care to properly manage critical objects within the web application.
The big reason why Dependency Injection has gained such prominence among web developers is that it allows us to easily manage these objects from a central configuration without convoluting our code or require overloads. And as with most frameworks, we can take advantage of functionality that is difficult to implement on our own.
The biggest advantage is the support of “web scoping”, that is we can scope objects to work well on the web. Often this means providing at least the following three scope levels:
- Application
- Session
- Request
This is in addition to runtime scoping levels offered by most DI frameworks, usually:
- Singleton
- Transient
- Thread
The difference is, while the runtime scoping is useful, we have to remember that web applications are inherently multi-threaded, so a singleton will get shared by all users, similar to using the “Application” type web scope.
Probably the most important web scope is “request” since its often the best choice for those critical objects whose usage and scope mean the most to us, i.e. the database context (EF) or Session (NHibernate). I find that getting support for this web scope has been at the core of the last two projects I have worked on at West Monroe. The essence of this scope, is the object is resolved only one time per request. This is ideal for databases where keeping the connection open too long is not good as is opening a new connection each time we talk to the database; its a healthy middle.
I think Dependency Injection is a very important aspect of modern development, if only because it pushes you to build applications from smaller decoupled blocks of code that are easier to test and reuse. The fact that we can tightly control the scope of objects, both in a runtime and web context sense, is extremely useful and saves me from having to write and test that code myself.
There are MANY frameworks available and depending on your circumstances you should choose the one that fits best. For example, one client project is using Spring .NET which isnt even supported and considered archaic by most standards. Another, newer, project didnt even have Dependency Injection was constantly throwing sporadic errors from different areas. We wanted to use AutoFac (which is a newer framework) but due to the use of ASMX web services in the backend process (for which AutoFac support is questionable) we opted to use Ninject. For most of my side projects, I use AutoFac because its newer and supports many of the concepts that have made DI much easier since its inception.
I have also used StructureMap, Unity, and Castle Windsor in the past, so I am fortunate to have a wide experience with DI. I think developers should focus on understanding the strengths and weaknesses of each of these tools, it helps you to make the right decision. A great example of this is, the client using Spring .NET, we debated replacing Spring with Autofac. We ended up staying with Spring so as to not add an additional variable into an already tumultuous situation. Good thing to because we would find out about the support for Autofac with regard to ASMX.