Unity+MVC:实现IDependencyResolver接口需要注意的地方

ASP.NET MVC3提供了IDependencyResolver接口,实现该接口,并结合相应的“依赖注入容器”(比如:Unity)可以方便地对Controller进行依赖注入。

本文以Unity为例,说明一下实现IDependencyResolver接口需要注意的地方。

先看一下我们使用的实现代码:

namespace CNBlogs.Infrastructure.CrossCutting.IoC
{
public class IoCDependencyResolver : IDependencyResolver
{
#region Memebers
private IContainer _currentContainter;
#endregion

#region Constructors
public IoCDependencyResolver(IContainer container)
{
_currentContainter
= container;
}
#endregion

#region IDependencyResolver Members
public object GetService(Type serviceType)
{
return _currentContainter.Resolve(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return _currentContainter.ResolveAll(serviceType);
}
#endregion
}
}

这样实现后,访问时出现下面的错误:

The current type, System.Web.Mvc.IControllerFactory, is an interface and cannot be constructed.
Are you missing a type mapping

从这个错误可以分析出,ASP.NET MVC试图通过Unity解析IControllerFactory的实现,但我们在代码中并没有注册IControllerFactory的实现。

于是,我们手动注册一下,代码如下:

_currentContainer.RegisterType<IControllerFactory, DefaultControllerFactory>();

之前的错误消失了,却出现了新的错误:

The current type, System.Web.Mvc.IControllerActivator, is an interface and cannot be constructed.
Are you missing a type mapping?

又找不到另外一个接口(IControllerActivator)的实现,难道要手工一个一个注册?

看来这不是解决之道,需要另辟捷径...

在codeplex中发现了Unity.MVC3(也是通过Unity实现ASP.NET MVC Contorller的依赖注入),学习了一下它的代码,发现了解决之道。

原来只需在IDependencyResolver.GetService(Type serviceType)的实现中,判断一下serviceType是否被注册,如果没有被注册,就返回null。ASP.NET MVC得到null返回值,会自己解析这个接口,这样问题就解决了,代码如下:

public object GetService(Type serviceType)
{
if (!_currentContainter.IsRegistered(serviceType))
{
return null;
}
return _currentContainter.Resolve(serviceType);
}

posted @ 2011-06-09 17:52  dudu  阅读(10585)  评论(4编辑  收藏  举报