简体   繁体   中英

Inject dependencies in a WebAPI with Unity

I have a WebAPI controller that (should) looks like this:

public class MyController : ApiController
{
    private IRepository repository;

    public MyController(IRepository repository) 
    {
        this.repository = repositor;
    }

    // REST implementations
}

WebApiConfig is configured like that:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Unity configuration
        var container = new UnityContainer();
        container
            .RegisterType<IRepository , CustomRepository>();
        config.DependencyResolver = new UnityResolver(container);

        // Web API routes
        // CORS
    }
}

then in Global.asax.cs I have something like:

public class WebApiApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        GlobalConfiguration.Configure(WebApiConfig.Register);
    }

    // CORS
    protected void Application_BeginRequest(object sender, EventArgs e)
    {
        // some CORS config
    } 
}

and finally I have a Startup.cs :

[assembly: OwinStartup(typeof(Path.To.Startup))]
namespace ZeroCode.ConfigurazioneServizio.Web.Api
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            new Mapping().Bootstrap();
        }
    }
}

To me everything looks ok, the code builds and I can launch the controller but as soon I make a request I get error cause parameterless constructor isn't present. So I've added the default constructor but this will instantiate the controller so IRepository will never be injected.

I've searched for a possible solution. One of them tried to implement IHttpControllerActivator and so i've realized something like this:

public class UnityHttpControllerActivator : IHttpControllerActivator
{
    private IUnityContainer _container;

    public UnityHttpControllerActivator(IUnityContainer container)
    {
        _container = container;
    }

    public IHttpController Create(System.Net.Http.HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
    {
        return (IHttpController)_container.Resolve(controllerType);
    }
}

At this point I've modified the WebApiConfig.cs inserting this line

config.Services.Replace(typeof(IHttpControllerActivator), new UnityHttpControllerActivator(container));

right after the config.DependencyResolver but this doesn't resolve the issue and exception is raised inside the Create method. I don't know what else I can do.

There's a nice little Nuget Package - Unity.Webapi . If you add that, you can simply plug in your container into your HttpConfiguration

public static void Register(HttpConfiguration config)
{
    // Unity configuration
    var container = new UnityContainer();
    container.RegisterType<IRepository , CustomRepository>();
    config.DependencyResolver = new UnityResolver(container);

    //this
    config.DependencyResolver = new UnityDependencyResolver(container);

    // Web API routes
    // CORS
}

Then you can bypass the extra class and web.config changes.

The first answer states to add Unity.WebApi . It is correct. After adding this package use it as is described in this link Using Unity.Mvc5 and Unity.WebApi together in a project . I did like this and my problem was solved.

With version 5 or higher for unity, you will have to add the Unity.AspNet.WebApi NuGet package. Then you can simply follow the instructions in the NuGet package to register your types and register your dependency resolver like the below:

using Unity.AspNet.WebApi;
config.DependencyResolver =  new UnityDependencyResolver(container);

Link to NuGet package: https://github.com/unitycontainer/aspnet-webapi

This is 3 step process :

  1. Register
  2. Resolve
  3. Link resolver to GlobalConfiguration

It appears you have not added resolving code and neither does above solutions.

Add this line before attaching DependencyResolver to GlobalConfiguration .

DependencyResolver.SetResolver(new UnityDependencyResolver(container));

You need to set up Unity as the dependency resolver for WebAPI.

Add the following NuGet package to your project: https://www.nuget.org/packages/Unity.WebAPI/

And then configure WebAPI to use the right resolver adding the following to your WebApiConfig.cs

        GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);

I had the same problem. For me the solution to this exact error was that all other controllers constructors also was loaded at request time. And one of them had not a valid parameter in the constructor. It was not registered with Unity.

So I got the resolution fail from Unity.

But after fixing that other controller everything worked fin.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM