I am trying to follow this guide to create a logical separation in my MVC app between the API portion and the MVC portion:
Here is my implementation of the extension method he is using:
public static IApplicationBuilder UseBranchWithServices(this IApplicationBuilder app,
PathString path, Action<IServiceCollection> servicesConfiguration,
Action<IApplicationBuilder> appBuilderConfiguration)
{
var webhost = new WebHostBuilder()
.UseKestrel()
.ConfigureServices(servicesConfiguration)
.UseStartup<StartupHarness>()
.Build()
/* ojO */ .CreateOrMigrateDatabase(); /* Ojo */
var serviceProvider = webhost.Services;
var featureCollection = webhost.ServerFeatures;
var appFactory = serviceProvider.GetRequiredService<IApplicationBuilderFactory>();
var branchBuilder = appFactory.CreateBuilder(featureCollection);
var factory = serviceProvider.GetRequiredService<IServiceScopeFactory>();
branchBuilder.Use(async (context, next) => {
using (var scope = factory.CreateScope()) {
context.RequestServices = scope.ServiceProvider;
await next();
}
});
appBuilderConfiguration(branchBuilder);
var branchDelegate = branchBuilder.Build();
return app.Map(path, builder => { builder.Use(async (context, next) => {
await branchDelegate(context);
});
});
}
When I try to use this and the SignInManager together, HttpContext is always null.
Here's a ridiculously simplified version of my AccountController:
public AccountController(SignInManager<AppUser> mgr) {
_mgr = mgr;
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (ModelState.IsValid)
{
var result = await _mgr.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, lockoutOnFailure: false);
}
}
I am calling app.UseAuthentication()
in the ApplicationBuilder; for purposes of brevity, I have that setup as an extension method. This works:
public void ConfigureServices(IServiceCollection services)
{
services.ConfigureMvcServices(Configuration);
}
public void Configure(IApplicationBuilder builder, IHostingEnvironment env)
{
builder.ConfigureMvcBuilder(env);
}
This does not:
public void Configure(IApplicationBuilder builder, IHostingEnvironment env)
{
builder.UseBranchWithServices(StaticConfiguration.RootPath,
services =>
{
services.ConfigureMvcServices(Configuration);
},
app => { app.ConfigureMvcBuilder(env); }
);
builder
.Run(async c =>
await c.Response.WriteAsync("This should work"));
}
In the latter example, the services
object ends up with a Count
of 335 descriptors, in the former (working) example it has 356.
I tried looking over this blog to see if I could figure out what is going on, but I don't see a strong correlation between what's in the method and what Gordon is describing. So I'm totally lost. Any help would be appreciated. If there's a way to split up the extension method and pass in the services for each pipeline, that would be fine with me.
Yes I know you only see one pipeline here. The point is to add more.