简体   繁体   中英

Difficulty constructing a controller with injected dependencies in Unity ASP.NET Web API

I know there are similar questions for this out there, but I've spent hours trying to follow them to no avail so I would really appreciate some help.

I'm working on a simple ASP.NET MVC project, and I'm trying to inject dependencies into a Web API Controller with Unity. The basic structure is:

EmailController <- NotificationEngine <- EmailAccessor

EmailAccessor's constructor needs to have injected values from Web.config AppSettings. EmailController and NotificationEngine only take a single object in their constructors. Here's an abridged version of the code:

EmailAccessor

public class EmailAccessor : IEmailAccessor
{
    private string senderEmail;
    private string senderUsername;
    private string senderPassword;
    private int port;

    public EmailAccessor(string senderEmail, string senderUsername, string senderPassword, int port)
    {
        this.senderEmail = senderEmail;
        this.senderUsername = senderUsername;
        this.senderPassword = senderPassword;
        this.port = port;
    }
    //...
}

NotificationEngine

public class NotificationEngine : INotificationEngine
{
    private IEmailAccessor emailAccessor;

    public NotificationEngine(IEmailAccessor emailAccessor)
    {
        this.emailAccessor = emailAccessor;
    }
    //...
}

EmailController

[RoutePrefix("api/email")]
public class EmailController : ApiController
{
    private INotificationEngine notificationEngine;

    public EmailController(INotificationEngine notificationEngine)
    {
        this.notificationEngine = notificationEngine;
    }

    [HttpPost]
    [Route("send")]
    public void Post([FromBody] EmailNotification email)
    {
        //...
    }
    //...
}

UnityConfig

Finally, here's the class where I register my types

public static class UnityConfig
{
    public static void RegisterTypes(IUnityContainer container)
    {
        container.LoadConfiguration();

        //...

        container.RegisterType<IEmailAccessor, EmailAccessor>(new InjectionConstructor(
                ConfigurationManager.AppSettings["SenderEmail"],
                ConfigurationManager.AppSettings["SenderUsername"],
                ConfigurationManager.AppSettings["SenderPassword"],
                int.Parse(ConfigurationManager.AppSettings["Port"])));
        container.RegisterType<INotificationEngine, NotificationEngine>();

        DependencyResolver.SetResolver(new UnityDependencyResolver(container));

    }
}

The settings are all pulled from <appSettings> in Web.config .

When I try and POST to localhost:63855/api/email/send , I get the following response:

{
    "Message": "No HTTP resource was found that matches the request URI 'http://localhost:63855/api/email/send'.",
    "MessageDetail": "No type was found that matches the controller named 'email'."
}

I'm working on a simple ASP.NET MVC project, and I'm trying to inject dependencies into a Web API Controller

It is not a "simple ASP.NET MVC project". It is a hybrid project with both ASP.NET MVC and Web API in it, which are 2 separate frameworks. Each of these frameworks has its own types and its own configuration.

You have configured DI with ASP.NET MVC, but not with Web API. To use both frameworks with DI, you must set the Dependency Resolver for both frameworks in your project.

// MVC's DependencyResolver
DependencyResolver.SetResolver(new UnityDependencyResolver(container));

// Web API's DependencyResolver
GlobalConfiguration.Configuration.DependencyResolver 
    = new UnityDependencyResolver(container);

This assumes that the UnityDependencyResolver you are using implements System.Web.Http.Dependencies.IDependencyResolver . If not, there are instructions on how to build one at Dependency Resolution with the Unity Container .

Also, be sure you have enabled attribute routing, or none of your Web API attribute routes will be picked up by the framework. This method must be called at application startup.

GlobalConfiguration.Configure(config =>
{
    // ** Enable Attribute Routing for Web API **
    config.MapHttpAttributeRoutes();

    // For the config you are showing, you don't necessarily need this
    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );
});

If that doesn't solve it, there is another similar question you should check out the answers for.

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