如果我想为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, Func<HttpRequestMessage, 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);
}
答案 0 :(得分:9)
Mark Seemann,.NET中的Dependency Injection的作者,有一篇关于DI与ASP.NET WebAPI的简短系列。
他将作品根放在IHttpControllerActivator
也许这有帮助。
<强>更新强>
GlobalConfiguration.Configuration.Services.Replace(
typeof(IHttpControllerActivator),
new PoorMansCompositionRoot());
在全球范围内注册您的自定义HttpControllerActivator
。
答案 1 :(得分:1)
在ASP.NET Web API HttpControllerDispatcher
中负责构建控制器。默认情况下,它与DependecyResolver一起使用,但如果要扩展其功能,则需要覆盖其SendAsync方法并再次注册。
示例:
public class MyCustomDispatcher : HttpControllerDispatcher {
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
CancellationToken cancellationToken) {
// Do your stuff here
// According to your requirements, either run its default functionality
// or return your own stuff
return base.SendAsync(request, cancellationToken);
}
}
注意:
但是,我找不到更换默认方式的优雅方法 全球。您可以轻松替换默认的每个路由 将此自定义调度程序附加到路由但似乎没有 全球范围内这样做的方式。我在那里开了一个讨论 项目网站:http://aspnetwebstack.codeplex.com/discussions/400366