/*
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
* See https://github.com/openiddict/openiddict-core for more information concerning
* the license and the contributors participating to this project.
*/
using System.ComponentModel;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
namespace OpenIddict.Server.Owin;
///
/// Provides the entry point necessary to instantiate and register the scoped
/// in an OWIN/Katana pipeline.
///
[EditorBrowsable(EditorBrowsableState.Advanced)]
public sealed class OpenIddictServerOwinMiddlewareFactory : OwinMiddleware
{
///
/// Creates a new instance of the class.
///
/// The next middleware in the pipeline, if applicable.
public OpenIddictServerOwinMiddlewareFactory(OwinMiddleware? next)
: base(next)
{
}
///
/// Resolves the instance from the OWIN context
/// and creates a new instance of the class,
/// which is used to register in the pipeline.
///
/// The .
///
/// A that can be used to monitor the asynchronous operation.
///
public override Task Invoke(IOwinContext context)
{
ArgumentNullException.ThrowIfNull(context);
var provider = context.Get(typeof(IServiceProvider).FullName) ??
throw new InvalidOperationException(SR.GetResourceString(SR.ID0121));
// Note: the Microsoft.Extensions.DependencyInjection container doesn't support resolving services
// with arbitrary parameters, which prevents the server OWIN middleware from being resolved directly
// from the DI container, as the next middleware in the pipeline cannot be specified as a parameter.
// To work around this limitation, the server OWIN middleware is manually instantiated and invoked.
var middleware = new OpenIddictServerOwinMiddleware(
next: Next,
options: GetRequiredService>(provider),
dispatcher: GetRequiredService(provider),
factory: GetRequiredService(provider));
return middleware.Invoke(context);
static T GetRequiredService(IServiceProvider provider) => provider.GetService() ??
throw new InvalidOperationException(SR.GetResourceString(SR.ID0122));
}
}