.net Simple Injector. register webApiControllers no parameterless public constructor

246 Views Asked by At

I have an error after I am trying to call my webApi controller,

An error occurred when trying to create a controller of type 'DrinkController'. Make sure that the controller has a parameterless public constructor.

Here is my Bootstrapper.cs

public class Bootstrapper
{
    public Container Start(HttpConfiguration configuration)
    {
        var container = new Container();
        container.Options.DefaultScopedLifestyle = new LifetimeScopeLifestyle();

        var conString = ConfigurationManager.ConnectionStrings["DrinksContext"].ConnectionString;
        container.Register(() => new DrinksContext(conString), Lifestyle.Scoped);

        container.Register<IUserManager, UserManager>();
        container.Register<IDrinkManager, DrinkManager>();
        container.Register<IOrderManager, OrderManager>();
        container.Register<IUnitOfWork, UnitOfWork>();

        container.RegisterWebApiControllers(configuration);

        container.Verify();
        return container;
    }
}

and here how I call him in Global.asax.cs

void Application_Start(object sender, EventArgs e)
    {
        // Code that runs on application startup
        AreaRegistration.RegisterAllAreas();
        GlobalConfiguration.Configure(WebApiConfig.Register);
        RouteConfig.RegisterRoutes(RouteTable.Routes);

        var container = new Bootstrapper().Start(GlobalConfiguration.Configuration);

        GlobalConfiguration.Configuration.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);
        DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));

        HttpConfiguration config = GlobalConfiguration.Configuration;

        config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
        config.Formatters.JsonFormatter.UseDataContractJsonSerializer = false;
    }

Controller ->

private readonly IOrderManager _orderManager;
    private readonly IDrinkManager _drinkManager;

    public DrinkController(IOrderManager orderManager, IDrinkManager drinkManager)
    {
        _orderManager = orderManager;
        _drinkManager = drinkManager;
    }

UnitiOfWork constructor depended from DrinksContext;

Postman response - here

I am injecting UnitOfWork into my managers. DrinksContext should reinitialize per each request. When line container.RegisterWebApiControllers(configuration) executes controller constructor fired, but when just a call from Postman - no. How I can resolve it? Thanks.

2

There are 2 best solutions below

0
On BEST ANSWER

If you look into the inner exception of the thrown exception, you will see the following information:

The Object is registered as 'Lifetime Scope' lifestyle, but the instance is requested outside the context of a Lifetime Scope.

This is because a lifetime scope needs to be started explicitly. The lifetime scope however is unsuited to work with both MVC and Web API due to the asynchronous behavior of both frameworks. Since you are running inside IIS, you should use WebRequestLifestyle as the default scoped lifestyle.

1
On

i think the problem is in your Unity config file.. maybe try to do this:

 public Container Start(HttpConfiguration configuration)
    {
        var container = new Container();
        container.Options.DefaultScopedLifestyle = new LifetimeScopeLifestyle();

        var conString = ConfigurationManager.ConnectionStrings["DrinksContext"].ConnectionString;
        container.Register(() => new DrinksContext(conString), Lifestyle.Scoped);

        container.Register<IUserManager, UserManager>();
        container.Register<IDrinkManager, DrinkManager>(new InjectionConstructor());
        container.Register<IOrderManager, OrderManager>(new InjectionConstructor());
        container.Register<IUnitOfWork, UnitOfWork>();

        container.RegisterWebApiControllers(configuration);

        container.Verify();
        return container;
    }

To call the dafult empty contructor of your class implementation (if you have more than one contructor.. Unityt choose the one with more parameter..so if you want to choose the empty one you can use new InjectionConstructor() or put in the constructor of your class the decoration [InjectionConstructor])

Hope it help