I'm confused with Autofac Examples : WebApiExample.OwinSelfHost, the startup class is following:
public class Startup
{
public void Configuration(IAppBuilder app)
{
// In OWIN you create your own HttpConfiguration rather than
// re-using the GlobalConfiguration.
var config = new HttpConfiguration();
config.Routes.MapHttpRoute(
"DefaultApi",
"api/{controller}/{id}",
new { id = RouteParameter.Optional });
var builder = new ContainerBuilder();
// Register Web API controller in executing assembly.
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
// OPTIONAL - Register the filter provider if you have custom filters that need DI.
// Also hook the filters up to controllers.
builder.RegisterWebApiFilterProvider(config);
builder.RegisterType<CustomActionFilter>()
.AsWebApiActionFilterFor<TestController>()
.InstancePerRequest();
// Register a logger service to be used by the controller and middleware.
builder.Register(c => new Logger()).As<ILogger>().InstancePerRequest();
// Autofac will add middleware to IAppBuilder in the order registered.
// The middleware will execute in the order added to IAppBuilder.
builder.RegisterType<FirstMiddleware>().InstancePerRequest();
builder.RegisterType<SecondMiddleware>().InstancePerRequest();
// Create and assign a dependency resolver for Web API to use.
var container = builder.Build();
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
// The Autofac middleware should be the first middleware added to the IAppBuilder.
// If you "UseAutofacMiddleware" then all of the middleware in the container
// will be injected into the pipeline right after the Autofac lifetime scope
// is created/injected.
//
// Alternatively, you can control when container-based
// middleware is used by using "UseAutofacLifetimeScopeInjector" along with
// "UseMiddlewareFromContainer". As long as the lifetime scope injector
// comes first, everything is good.
app.UseAutofacMiddleware(container);
// Again, the alternative to "UseAutofacMiddleware" is something like this:
// app.UseAutofacLifetimeScopeInjector(container);
// app.UseMiddlewareFromContainer<FirstMiddleware>();
// app.UseMiddlewareFromContainer<SecondMiddleware>();
// Make sure the Autofac lifetime scope is passed to Web API.
app.UseAutofacWebApi(config);
app.UseWebApi(config);
}
}
The FirstMiddleware and SecondMiddleware code was as following:
public class FirstMiddleware : OwinMiddleware
{
private readonly ILogger _logger;
public FirstMiddleware(OwinMiddleware next, ILogger logger) : base(next)
{
this._logger = logger;
}
public override async Task Invoke(IOwinContext context)
{
this._logger.Write("Inside the 'Invoke' method of the '{0}' middleware.", GetType().Name);
await Next.Invoke(context);
}
}
public class SecondMiddleware : OwinMiddleware
{
private readonly ILogger _logger;
public SecondMiddleware(OwinMiddleware next, ILogger logger) : base(next)
{
this._logger = logger;
}
public override async Task Invoke(IOwinContext context)
{
this._logger.Write("Inside the 'Invoke' method of the '{0}' middleware.", GetType().Name);
await Next.Invoke(context);
}
}
According to the comments, the middleware registration order matters. FirstMiddleware first, then SecondMiddleware. but the output was second middleware was invoked first. the program logs output here
What's wrong with the order? This is the autofac official example.WebApiExample.OwinSelfHost
Looks like you've found a bug! I've filed an issue about it on your behalf. You can read more technical details about it there, but the short version is that over the years we've changed some Autofac internals to support .NET Core and this looks like something we've missed.
The workaround until this is fixed will be to register the middleware in reverse order, which isn't awesome because once the fix is applied you'll have to reverse them back. :(