If you've been paying attention to the chatter around ASP.NET MVC 3 you'll know the extensibility in MVC 3 is handled through a dependency resolver. It's not another IOC container but rather an adapter to whatever IOC container you're already comfortable with. There are two methods that need to be hooked up.
public interface IDependencyResolver
{
object GetService(Type serviceType);
IEnumerable<object> GetServices(Type serviceType);
}
If you're using one of the more common IOC containers in the .NET space, you're probably already covered. Most already have implementations of IDependencyResolver
available through NuGet or on various blogs. However, if you've rolled your own IOC container, or, like me, already use a custom IOC adapter (more here), you'll probably have to implement IDependencyResolver
yourself.
If your custom IOC container or adapter only has generic methods, here's where you might run into a little bit of trouble.
public class MyDependencyResolver : IDependencyResolver
{
public object GetService(Type serviceType)
{
// Most containers throw an exception if the service
// type can't be found. GetService expects a null.
if (!GetServices(serviceType).Any())
return null;
return MyContainer.MyGet< // um...
}
public IEnumerable<object> GetServices(Type serviceType)
{
return MyContainer.MyGetAll< // oh crap
}
}
It's not immediately obvious how to take a type and call a generic method with it, at least it wasn't to me. It's easy to take a generic type parameter and convert that into a type with typeof
, but I was surprised to realise I had never gone the other way, at least not in recent memory. Luckily someone was at hand who knew how to do it. Many thanks to Angus Douglas.
Here it is using reflection with GetMethod
and MakeGenericMethod
.
public class MyDependencyResolver : IDependencyResolver
{
public MyDependencyResolver()
{
// The types are only needed if the MyGet method is overloaded.
MyGetMethod = typeof(MyContainer).GetMethod("MyGet", new Type[0]);
// The types are only needed if the MyGetAll method is overloaded.
MyGetAllMethod = typeof(MyContainer).GetMethod("MyGetAll", new Type[0]);
}
private MethodInfo MyGetMethod { get; set; }
private MethodInfo MyGetAllMethod { get; set; }
public object GetService(Type serviceType)
{
// Most containers throw an exception if the service
// type can't be found. GetService expects a null.
if (!GetServices(serviceType).Any())
return null;
MethodInfo myGetMethod = MyGetMethod.MakeGenericMethod(new[] { serviceType });
return myGetMethod.Invoke(null, null);
}
public IEnumerable<object> GetServices(Type serviceType)
{
MethodInfo myGetAllMethod = MyGetAllMethod.MakeGenericMethod(new[] { serviceType });
return (IEnumerable<object>)myGetAllMethod.Invoke(null, null);
}
}
For completeness, all that remains is hooking up the dependency resolver in Global.asax.cs
.
protected void Application_Start()
{
// Inversion of Control / Dependency Injection
// Insert custom IOC container/adapter initialisation here.
MyContainer.MyGet<IKernel>().Load(new MyNinjectModule());
// Hook up MyDependencyResolver.
DependencyResolver.SetResolver(new MyDependencyResolver());
// MVC Plumbing
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
There are 0 comments.
browse with Pivot
Codility Nitrogenium Challenge
OS X Lock
HACT '13
Codility Challenges
Priority Queue
Architecture (13)
ASP.NET (2)
ASP.NET MVC (13)
Brisbane Flood (1)
Building Neno (38)
C# (4)
Challenges (3)
Collections (1)
Communicator (1)
Concurrency Control (2)
Configuration (1)
CSS (5)
DataAnnotations (2)
Database (1)
DotNetOpenAuth (2)
Entity Framework (1)
FluentNHibernate (2)
Inversion of Control (5)
JavaScript (1)
jQuery (4)
Kata (2)
Linq (7)
Markdown (4)
Mercurial (5)
NHibernate (20)
Ninject (2)
OpenID (3)
OS X (1)
Pivot (6)
PowerShell (8)
Prettify (2)
RSS (1)
Spring (3)
SQL Server (5)
T-SQL (2)
Validation (2)
Vim (1)
Visual Studio (2)
Windows Forms (3)
Windows Service (1)
Comments
Leave a Comment
Please register or login to leave a comment.