如果我想为ASP.NET MVC控制器实现依赖注入,我可以使用IControllerFactory接口创建一个工厂类,然后在Global.asax.cs中注册,如:
ControllerBuilder.Current.SetControllerFactory(controllerFactory)
(参考:http://www.dotnetcurry.com/ShowArticle.aspx?ID=786)
现在我的问题是:
如何为IHttpControllerActivator派生类设置工厂?
我们有ASP.NET MVC 4.0中的东西,像:
HttpControllerBuilder.Current.SetApiControllerActivator(httpControllerActivator)
?
更新:
我定制的HttpControllerActivator:
public class MyCustomApiActivator : DefaultHttpControllerActivator //or IHttpControllerActivator ? { private readonly Dictionary<string,Func<HttpRequestMessage,IHttpController>> _apiMap; public MyCustomApiActivator(IMyRepository repository) { if (repository == null) { throw new ArgumentException("repository"); } _apiMap = new Dictionary<string,IHttpController>>(); controllerMap["Home"] = context => new HomeController(); _apiMap["MyCustomApi"] = context => new MyCustomApiController(repository); } public IHttpController Create(HttpRequestMessage request,HttpControllerDescriptor controllerDescriptor,Type controllerType) { if(_apiMap.ContainsKey(controllerType.Name)) return _apiMap[controllerType.Name](request); return null; } }
我的组成根:
public class CompositionRoot { private readonly IHttpControllerActivator _apiControllerActivator; public CompositionRoot() { _apiControllerActivator = CompositionRoot.CreateHttpControllerActivator(); } public IHttpControllerActivator ApiControllerActivator { get { return _apiControllerActivator; } } private static IHttpControllerActivator CreateHttpControllerActivator() { string defaultRepositoryTypeName = ConfigurationManager.AppSettings["DefaultRepositoryTypeName"]; var defaultRepositoryType = Type.GetType(defaultRepositoryTypeName,true); var defaultRepository = (IMyRepository)Activator.CreateInstance(defaultRepositoryType); var apiController = new MyCustomApiActivator(defaultRepository); return apiController; } }
最后这是在我的Global.asax.cs里面,我需要一个技巧:
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); var root = new CompositionRoot(); //The following line raise this compile-time error: // cannot convert from 'System.Web.Http.Dispatcher.IHttpControllerActivator' // to 'System.Web.Mvc.IControllerFactory' ControllerBuilder.Current.SetControllerFactory(root.ApiControllerActivator); }
Dependency Injection在.NET中的作者Mark Seemann在DI上与ASP.NET WebAPI有一个简短的系列.
他将组合根放在IHttpControllerActivator中
> Dependency Injection and Lifetime Management with ASP.NET Web API
> Dependency Injection in ASP.NET Web API with Castle Windsor
也许这有帮助.
更新
GlobalConfiguration.Configuration.Services.Replace( typeof(IHttpControllerActivator),new PoorMansCompositionRoot());