If I want to implement a Dependency Injection for ASP.NET MVC controllers, I can use IControllerFactory
interface to create a factory class and then register it in Global.asax.cs, like:
ControllerBuilder.Current.SetControllerFactory(controllerFactory)
(reference: http://www.dotnetcurry.com/ShowArticle.aspx?ID=786)
Now my question is:
How could I set a factory for an IHttpControllerActivator
derived class?
Do we have something in ASP.NET MVC 4.0 like:
HttpControllerBuilder.Current.SetApiControllerActivator(httpControllerActivator)
?
Update:
I want to add my current code, it might be helpful to understand the case:
My customized 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;
}
}
My composition root:
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;
}
}
Finally this is inside my Global.asax.cs
, where I need a trick:
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);
}
Web API (Application Programming Interface) in ASP.NET is an extensible framework for creating the HTTP (Hypertext Transfer Protocol) services which can be right to use from any of the clients such as web browsers, desktop applications, mobile devices and IOTs (Internet of Things).
From the File menu, select New > Project. Select the ASP.NET Core Web API template and click Next. Name the project TodoApi and click Create. In the Create a new ASP.NET Core Web Application dialog, confirm that .NET Core and ASP.NET Core 5.0 are selected.
Select Controller Folder And add New Controller. Select Web Api 2 Conroller Empty Click OK. Write Web Api Get Method . "DemoEntities" is a Entity framwork class name.
To learn more, visit the Web API documentation. ASP.NET makes it easy to build services that reach a broad range of clients, including browsers and mobile devices. With ASP.NET you use the same framework and patterns to build both web pages and services, side-by-side in the same project. ASP.NET was designed for modern web experiences.
Mark Seemann, author of Dependency Injection in .NET, has a short series on DI with ASP.NET WebAPI.
He places the composition root inside an IHttpControllerActivator
Maybe that helps.
Update
GlobalConfiguration.Configuration.Services.Replace(
typeof(IHttpControllerActivator),
new PoorMansCompositionRoot());
Registers your custom HttpControllerActivator
globally.
In ASP.NET Web API HttpControllerDispatcher
is responsible for constructing controllers. It works with the DependecyResolver by default but if you want to extend its functionality, you need to override its SendAsync method and register it again.
Example:
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);
}
}
Note:
However, I wasn't able to find an elegant way to replace the default one globally. You can replace the default one per-route easily by attaching this custom dispatcher to a route but there seems to be no way to do this globally. I opened up a discussion on that at the project site: http://aspnetwebstack.codeplex.com/discussions/400366
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With