ASP.NET MVC offers many benefits over classical WebForms (which I honestly stopped even thinking of). One of the advantages is separation of concerns. We can even further enhance app design and separation by utilising inversion of control and dependency injection. It doesn't really matter which container you are using, as they all pretty much offer the same functionality. Here I am using Castle Windsor.
Let’s take a look at a simple sample of how to inject a dependency into ASP.NET MVC Controller. A very common task would be injecting a repository into the controller's constructor. So let's do that. Consider a basic repository interface and a dummy class that implements it
public interface IDepartmentRepository
{
IEnumerable<string> GetDepartments();
IEnumerable<Employee> GetEmployeesByDepartment(string deptName);
}
public class DeparmentRepository : IDepartmentRepository
{
private static List<Employee> data = new List<Employee>();
static DeparmentRepository()
{
//dummy data
//in reality it comes from DB or other sources
data.Add(new Employee { Department = "Sales",
Name = "Alan McMillan",
Position = "Senior Manager" });
data.Add(new Employee { Department = "Sales",
Name = "Din Shawn",
Position = "Manager" });
//...
}
public IEnumerable<string> GetDepartments()
{
return (from d in data
orderby d.Department ascending
select d.Department).Distinct();
}
public IEnumerable<Employee> GetEmployeesByDepartment(string deptName)
{
return from e in data
orderby e.Department ascending
select e;
}
}
Small notice, it is a good idea to return IEnumerable for collections instead of IList or IQueryable. That's of course depends, but as a general rule it is a good practise.
Next, let’s say I want to see all the department on my web page (by calling a GetDepartments method). Controller for such page might be defined as following
public class DepartmentController : Controller
{
private IDepartmentRepository deptRepository;
public DepartmentController(IDepartmentRepository departmentRepository)
{
deptRepository = departmentRepository;
}
public ActionResult GetDepartments()
{
var dept = deptRepository.GetDepartments();
return Json(dept, JsonRequestBehavior.AllowGet);
}
public ActionResult Index()
{
return View();
}
}
Controller is inherited from the default implementation and not a custom one. In run time, an instance of the IDepartmentRepository interface will resolved and injected by the IoC container. By default, ASP.NET MVC doesn’t know about my interfaces and classes (that implement interfaces), therefore we need to show explicitly what to inject. In other words, we need to have a custom controller factory.
public class CustomControllerFactory : DefaultControllerFactory
{
public CustomControllerFactory()
{
var controllers = AllTypes
.FromThisAssembly()
.BasedOn(typeof(IController))
.Configure(c => c.LifeStyle.Is(LifestyleType.Transient));
ContainerService.Instance.Register(controllers);
}
protected override IController GetControllerInstance(
RequestContext requestContext, Type controllerType)
{
if (controllerType != null)
{
return (IController)ContainerService.Instance.Resolve(controllerType);
}
return base.GetControllerInstance(requestContext, controllerType);
}
}
Once we have this simple factory, that is by the way is not aware of the types it will be instantiating as it looks for IController children, we will need to direct the run time to use our custom factory instead of the default one. It can done by by updating global.asax.
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
//use custom factory
var controllerFactory = new CustomControllerFactory();
ControllerBuilder.Current.SetControllerFactory(controllerFactory);
}
Lastly, interface of the repository and the class implementation needs to be registered with IoC container. This is how it finds what to inject. I quite like to keep domain types registration in one place, e.g. inside Initialize method of my custom Container class
public IWindsorContainer Initialize()
{
if (!isConfigured)
{
container = new WindsorContainer();
container.Register(Component.For<IDepartmentRepository>()
.ImplementedBy<DeparmentRepository>());
isConfigured = true;
}
return container;
}
That’s it. We are done with the logic. Let’s test our implementation and see if it works. Consider a basic Razor page that makes an ajax call to the GetDepartments method of the DeparmentRepository and displays the result, say as a simple client side alert
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<title>Departments</title>
<script type="text/javascript"
src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js">
</script>
<script type="text/javascript">
$(document).ready(function () {
$.ajax({
url: '/department/getdepartments',
type: 'GET',
success: function (result) { alert(result); }
});
});
</script>
</head>
<body>
</body>
</html>
Finally, you should now be able to see data pulled from the repository and the whole thing working

There are many other cool features with DI and controllers, this post is just a basic kick-off point.
Update: I have added a sample ASP.NET MVC 3 project to illustrate all this.
JQueryTemplateSample.zip (213.76 kb) [Downloads: 270]

If you enjoyed this post, make sure you subscribe to my RSS feed!
5746b648-bbbb-4560-9521-ff2cdd21ad84|0|.0
Dependency injection is now heavily applied in software development. I find it useful to utilize a separate project for injections of types.
Typically, I have a library type project that is called a Container (really clever I know). This project has references to inversion of control container, such as Castle Windsor (see the list of others), plus a link to the core project. Thus it depends on the underlying IoC container and simple domain types. To see clearly what I can do with such container I have a base interface
public interface IContainer
{
void Register(params IRegistration[] regParams);
T Resolve<T>();
Type Resolve(Type type);
void Dispose();
}
This interface is implemented by the Container class. All the main types are registered by the Initialize method. If I need to register additional types, like controllers from ASP.NET MVC presentation layer, I can do it later by calling the Register method.
public class Container : IContainer, IDisposable
{
private static bool isConfigured;
private static readonly object synchRoot = new object();
private IWindsorContainer container;
#region IContainer Members
public void Register(params IRegistration[] regParams)
{
Initialize();
container.Register(regParams);
}
public void Dispose()
{
if (container != null)
{
container.Dispose();
container = null;
}
}
public T Resolve<T>()
{
return container.Resolve<T>();
}
public Type Resolve(Type type)
{
return (Type) container.Resolve(type);
}
#endregion
public IWindsorContainer Initialize()
{
lock (synchRoot)
{
if (!isConfigured)
{
container = new WindsorContainer();
container.Register(
Component
.For<IRandomBitGenerator>()
.ImplementedBy<RandomBitGenerator>());
//...
isConfigured = true;
}
}
return container;
}
}
This class is managed through the service that allows a single instance of the container. Multithreading is implemented on the lower level by IoC container itself.
public class ContainerService
{
/// <summary>
/// Returns lazily loaded Container
/// </summary>
public static IContainer Instance
{
get { return LazyLoadingContainerService.instance; }
}
#region Nested type: LazyLoadingContainerService
internal class LazyLoadingContainerService
{
// Explicit static constructor to tell
//C# compiler not to mark type as beforefieldinit
internal static readonly Container instance;
static LazyLoadingContainerService()
{
instance = new Container();
instance.Initialize();
}
}
#endregion
}
Such implementation can be used in the following way
public abstract class AbstractUtilsTest
{
protected IRandomBitGenerator rndBitGenerator;
protected AbstractUtilsTest()
{
rndBitGenerator = ContainerService.Instance
.Resolve<IRandomBitGenerator>();
}
}
If you enjoyed this post, make sure you subscribe to my RSS feed!
23a9d543-7b08-40e2-9df9-6374f2d4fbad|1|5.0
Tags: IoC |
Categories: .NET
Posted by
oleksii on
1/4/2011 7:56 PM |
Comments (0)
A list of some .NET IoC containers (dedicated or as part of a framework) sorted alphabetically:
* New or not constantly developed
If you enjoyed this post, make sure you subscribe to my RSS feed!
f3ed04b5-0e17-4f41-8ea0-ab7668b97f05|0|.0