diff --git a/src/OpenIddict.Abstractions/Resources/OpenIddictResources.resx b/src/OpenIddict.Abstractions/Resources/OpenIddictResources.resx
index 6b1b842c..089b2d29 100644
--- a/src/OpenIddict.Abstractions/Resources/OpenIddictResources.resx
+++ b/src/OpenIddict.Abstractions/Resources/OpenIddictResources.resx
@@ -1389,6 +1389,10 @@ To register the OpenIddict core services, reference the 'OpenIddict.Core' packag
Provided symmetric key was incorrect size. Expected {0} bits, received {1}.
{Locked}
+
+ The context type associated with the specified descriptor doesn't match the context type of this builder.
+ {Locked}
+
The security token is missing.
diff --git a/src/OpenIddict.Server/OpenIddictServerBuilder.cs b/src/OpenIddict.Server/OpenIddictServerBuilder.cs
index 3342af6b..e586f9bb 100644
--- a/src/OpenIddict.Server/OpenIddictServerBuilder.cs
+++ b/src/OpenIddict.Server/OpenIddictServerBuilder.cs
@@ -157,8 +157,7 @@ namespace Microsoft.Extensions.DependencyInjection
///
/// Registers an encryption key.
///
- /// The security key.
- ///
+ /// The security key.
/// The .
public OpenIddictServerBuilder AddEncryptionKey(SecurityKey key)
{
diff --git a/src/OpenIddict.Server/OpenIddictServerHandlerDescriptor.cs b/src/OpenIddict.Server/OpenIddictServerHandlerDescriptor.cs
index 82050ce9..808a6bdf 100644
--- a/src/OpenIddict.Server/OpenIddictServerHandlerDescriptor.cs
+++ b/src/OpenIddict.Server/OpenIddictServerHandlerDescriptor.cs
@@ -68,7 +68,7 @@ namespace OpenIddict.Server
public class Builder where TContext : BaseContext
{
private ServiceDescriptor? _descriptor;
- private readonly List _filterTypes = new List();
+ private readonly List _filters = new();
private int _order;
private OpenIddictServerHandlerType _type;
@@ -89,7 +89,7 @@ namespace OpenIddict.Server
throw new InvalidOperationException(SR.GetResourceString(SR.ID0104));
}
- _filterTypes.Add(type);
+ _filters.Add(type);
return this;
}
@@ -103,6 +103,33 @@ namespace OpenIddict.Server
where TFilter : IOpenIddictServerHandlerFilter
=> AddFilter(typeof(TFilter));
+ ///
+ /// Imports the properties set on the specified descriptor.
+ ///
+ /// The existing descriptor properties are copied from.
+ /// All the properties previously set on this instance are automatically replaced.
+ /// The builder instance, so that calls can be easily chained.
+ public Builder Import(OpenIddictServerHandlerDescriptor descriptor)
+ {
+ if (descriptor is null)
+ {
+ throw new ArgumentNullException(nameof(descriptor));
+ }
+
+ if (descriptor.ContextType != typeof(TContext))
+ {
+ throw new InvalidOperationException(SR.GetResourceString(SR.ID0284));
+ }
+
+ _descriptor = descriptor.ServiceDescriptor;
+ _filters.Clear();
+ _filters.AddRange(descriptor.FilterTypes);
+ _order = descriptor.Order;
+ _type = descriptor.Type;
+
+ return this;
+ }
+
///
/// Sets the service descriptor.
///
@@ -250,7 +277,7 @@ namespace OpenIddict.Server
public OpenIddictServerHandlerDescriptor Build() => new OpenIddictServerHandlerDescriptor
{
ContextType = typeof(TContext),
- FilterTypes = _filterTypes.ToImmutableArray(),
+ FilterTypes = _filters.ToImmutableArray(),
Order = _order,
ServiceDescriptor = _descriptor ?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0105)),
Type = _type
diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.Authentication.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.Authentication.cs
index b50c6859..976e8639 100644
--- a/src/OpenIddict.Server/OpenIddictServerHandlers.Authentication.cs
+++ b/src/OpenIddict.Server/OpenIddictServerHandlers.Authentication.cs
@@ -1150,11 +1150,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictScopeManager? _scopeManager;
- public ValidateScopes()
- {
- }
-
- public ValidateScopes(IOpenIddictScopeManager scopeManager)
+ public ValidateScopes(IOpenIddictScopeManager? scopeManager = null)
=> _scopeManager = scopeManager;
///
@@ -1163,7 +1159,7 @@ namespace OpenIddict.Server
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder()
.AddFilter()
- .UseScopedHandler(provider =>
+ .UseScopedHandler(static provider =>
{
// Note: the scope manager is only resolved if the degraded mode was not enabled to ensure
// invalid core configuration exceptions are not thrown even if the managers were registered.
diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.Device.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.Device.cs
index ca730c63..e117a402 100644
--- a/src/OpenIddict.Server/OpenIddictServerHandlers.Device.cs
+++ b/src/OpenIddict.Server/OpenIddictServerHandlers.Device.cs
@@ -372,11 +372,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictScopeManager? _scopeManager;
- public ValidateScopes()
- {
- }
-
- public ValidateScopes(IOpenIddictScopeManager scopeManager)
+ public ValidateScopes(IOpenIddictScopeManager? scopeManager = null)
=> _scopeManager = scopeManager;
///
@@ -385,7 +381,7 @@ namespace OpenIddict.Server
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder()
.AddFilter()
- .UseScopedHandler(provider =>
+ .UseScopedHandler(static provider =>
{
// Note: the scope manager is only resolved if the degraded mode was not enabled to ensure
// invalid core configuration exceptions are not thrown even if the managers were registered.
diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.Exchange.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.Exchange.cs
index d80e691a..4a677fab 100644
--- a/src/OpenIddict.Server/OpenIddictServerHandlers.Exchange.cs
+++ b/src/OpenIddict.Server/OpenIddictServerHandlers.Exchange.cs
@@ -701,11 +701,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictScopeManager? _scopeManager;
- public ValidateScopes()
- {
- }
-
- public ValidateScopes(IOpenIddictScopeManager scopeManager)
+ public ValidateScopes(IOpenIddictScopeManager? scopeManager = null)
=> _scopeManager = scopeManager;
///
@@ -714,7 +710,7 @@ namespace OpenIddict.Server
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder()
.AddFilter()
- .UseScopedHandler(provider =>
+ .UseScopedHandler(static provider =>
{
// Note: the scope manager is only resolved if the degraded mode was not enabled to ensure
// invalid core configuration exceptions are not thrown even if the managers were registered.
diff --git a/src/OpenIddict.Validation/OpenIddictValidationHandlerDescriptor.cs b/src/OpenIddict.Validation/OpenIddictValidationHandlerDescriptor.cs
index d4afd4a9..8a0bce77 100644
--- a/src/OpenIddict.Validation/OpenIddictValidationHandlerDescriptor.cs
+++ b/src/OpenIddict.Validation/OpenIddictValidationHandlerDescriptor.cs
@@ -68,7 +68,7 @@ namespace OpenIddict.Validation
public class Builder where TContext : BaseContext
{
private ServiceDescriptor? _descriptor;
- private readonly List _filterTypes = new List();
+ private readonly List _filters = new();
private int _order;
private OpenIddictValidationHandlerType _type;
@@ -89,7 +89,7 @@ namespace OpenIddict.Validation
throw new InvalidOperationException(SR.GetResourceString(SR.ID0104));
}
- _filterTypes.Add(type);
+ _filters.Add(type);
return this;
}
@@ -103,6 +103,33 @@ namespace OpenIddict.Validation
where TFilter : IOpenIddictValidationHandlerFilter
=> AddFilter(typeof(TFilter));
+ ///
+ /// Imports the properties set on the specified descriptor.
+ ///
+ /// The existing descriptor properties are copied from.
+ /// All the properties previously set on this instance are automatically replaced.
+ /// The builder instance, so that calls can be easily chained.
+ public Builder Import(OpenIddictValidationHandlerDescriptor descriptor)
+ {
+ if (descriptor is null)
+ {
+ throw new ArgumentNullException(nameof(descriptor));
+ }
+
+ if (descriptor.ContextType != typeof(TContext))
+ {
+ throw new InvalidOperationException(SR.GetResourceString(SR.ID0284));
+ }
+
+ _descriptor = descriptor.ServiceDescriptor;
+ _filters.Clear();
+ _filters.AddRange(descriptor.FilterTypes);
+ _order = descriptor.Order;
+ _type = descriptor.Type;
+
+ return this;
+ }
+
///
/// Sets the service descriptor.
///
@@ -250,7 +277,7 @@ namespace OpenIddict.Validation
public OpenIddictValidationHandlerDescriptor Build() => new OpenIddictValidationHandlerDescriptor
{
ContextType = typeof(TContext),
- FilterTypes = _filterTypes.ToImmutableArray(),
+ FilterTypes = _filters.ToImmutableArray(),
Order = _order,
ServiceDescriptor = _descriptor ?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0105)),
Type = _type