Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any HttpControllerBuilder for ASP.NET Web API?

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);
    }
like image 547
Tohid Avatar asked Oct 22 '12 19:10

Tohid


People also ask

What is ASP NET Web API?

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).

How do I create an API in ASP NET Core?

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.

How to create a web API 2 conroller?

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.

Where can I learn more about the web API?

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.


2 Answers

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

  1. Dependency Injection and Lifetime Management with ASP.NET Web API
  2. Dependency Injection in ASP.NET Web API with Castle Windsor

Maybe that helps.


Update

GlobalConfiguration.Configuration.Services.Replace(
  typeof(IHttpControllerActivator),
  new PoorMansCompositionRoot());

Registers your custom HttpControllerActivator globally.

like image 179
Sebastian Weber Avatar answered Sep 26 '22 00:09

Sebastian Weber


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

like image 36
tugberk Avatar answered Sep 24 '22 00:09

tugberk