After adding Simple Injector to my project to create an instance of my UserAppManager that will exist through the whole lifetime of a session I started to recieve errors:
Error with no parameterless constructor:
An error occurred when trying to create a controller of type 'AuthController'. Make sure that the controller has a parameterless public constructor.
Error with a parameterless constructor:
For the container to be able to create AuthController it should have only one public constructor: it has 2.
I followed a guide (https://simpleinjector.codeplex.com/discussions/564822) to avoid getting the UserManager from the Request.GetOwinContext() and doing it using the constructor but without luck. What am I doing wrong?
Startup:
public class Startup
{
public void Configuration(IAppBuilder app)
{
...
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
app.UseWebApi(httpConfig);
DependencyConfig.InjectDependencies(app);
}
}
AuthController:
[RoutePrefix("api/auth")]
public class AuthController : ApiController
{
readonly private AppUserManager _appUserManager;
public AuthController(AppUserManager appUserManager)
{
_appUserManager = appUserManager;
}
}
DependencyConfig:
public class DependencyConfig
{
public static void InjectDependencies(IAppBuilder app)
{
var container = new Container();
container.Options.DefaultScopedLifestyle = new WebApiRequestLifestyle();
container.Register<AppDbContext>(Lifestyle.Scoped);
container.Register<IUserStore<AppUser>>(() => new UserStore<AppUser>(container.GetInstance<AppDbContext>()), Lifestyle.Scoped);
container.Register<AppUserManager>(Lifestyle.Scoped);
// other service injections
container.RegisterWebApiControllers(GlobalConfiguration.Configuration);
container.Verify();
GlobalConfiguration.Configuration.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);
app.CreatePerOwinContext(() => container.GetInstance<AppUserManager>());
}
}
Looking at your code:
Startup.cs
DependencyConfig
Seems clear to me that you are not using the same
HttpConfiguration
instance for both the Web Api configuration and SimpleInjector registration.Please note that
GlobalConfiguration.Configuration
!=httpConfig
(except if you have manually assignedvar httpConfig = GlobalConfiguration.Configuration
).This way your Web API middleware has no knowledge of SimpleInjector, and will use its default implementation. Because of this the creation of your controller will fail.
Please use the same
HttpConfiguration
for both Web Api and SimpleInjector registration:Also, you need to provide just a single constructor for your controller, with every parameter you want to be injected inside it (remove the parameterless constructor).
Regarding
app.CreatePerOwinContext
I would be very careful in using this line:
You are requesting an instance of a
LifeStyle.Scoped
type inside Owin, but you declared the default scope asWebApiRequestLifestyle
. This life-style inherits fromExecutionContextScopeLifestyle
but the scope itself begins only on the start of a Web Api request, and thus I believe it will not be present in any middleware executed outside of Web API (maybe Steven could help us clarify this matter).You may consider using
WebRequestLifestyle
, but be aware of the possible issues with async/await.