diff --git a/src/OpenIddict.Core/OpenIddictCoreBuilder.cs b/src/OpenIddict.Core/OpenIddictCoreBuilder.cs
index e95ef524..ada6dd21 100644
--- a/src/OpenIddict.Core/OpenIddictCoreBuilder.cs
+++ b/src/OpenIddict.Core/OpenIddictCoreBuilder.cs
@@ -104,6 +104,29 @@ public sealed class OpenIddictCoreBuilder
return this;
}
+ ///
+ /// Replaces the application store by the specified type.
+ ///
+ ///
+ /// Note: the specified type MUST be an open generic type definition containing exactly one generic argument.
+ ///
+ /// The type of the store.
+ /// The lifetime of the store.
+ /// The instance.
+ public OpenIddictCoreBuilder ReplaceApplicationStore(
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type type,
+ ServiceLifetime lifetime = ServiceLifetime.Scoped)
+ {
+ if (!type.IsGenericTypeDefinition || type.GetGenericArguments() is not { Length: 1 })
+ {
+ throw new ArgumentException(SR.GetResourceString(SR.ID0232), nameof(type));
+ }
+
+ Services.Replace(ServiceDescriptor.Describe(typeof(IOpenIddictApplicationStore<>), type, lifetime));
+
+ return this;
+ }
+
///
/// Replaces the authorization manager by the specified type.
///
@@ -161,6 +184,29 @@ public sealed class OpenIddictCoreBuilder
return this;
}
+ ///
+ /// Replaces the authorization store by the specified type.
+ ///
+ ///
+ /// Note: the specified type MUST be an open generic type definition containing exactly one generic argument.
+ ///
+ /// The type of the store.
+ /// The lifetime of the store.
+ /// The instance.
+ public OpenIddictCoreBuilder ReplaceAuthorizationStore(
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type type,
+ ServiceLifetime lifetime = ServiceLifetime.Scoped)
+ {
+ if (!type.IsGenericTypeDefinition || type.GetGenericArguments() is not { Length: 1 })
+ {
+ throw new ArgumentException(SR.GetResourceString(SR.ID0232), nameof(type));
+ }
+
+ Services.Replace(ServiceDescriptor.Describe(typeof(IOpenIddictAuthorizationStore<>), type, lifetime));
+
+ return this;
+ }
+
///
/// Replaces the scope manager by the specified type.
///
@@ -218,6 +264,29 @@ public sealed class OpenIddictCoreBuilder
return this;
}
+ ///
+ /// Replaces the scope store by the specified type.
+ ///
+ ///
+ /// Note: the specified type MUST be an open generic type definition containing exactly one generic argument.
+ ///
+ /// The type of the store.
+ /// The lifetime of the store.
+ /// The instance.
+ public OpenIddictCoreBuilder ReplaceScopeStore(
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type type,
+ ServiceLifetime lifetime = ServiceLifetime.Scoped)
+ {
+ if (!type.IsGenericTypeDefinition || type.GetGenericArguments() is not { Length: 1 })
+ {
+ throw new ArgumentException(SR.GetResourceString(SR.ID0232), nameof(type));
+ }
+
+ Services.Replace(ServiceDescriptor.Describe(typeof(IOpenIddictScopeStore<>), type, lifetime));
+
+ return this;
+ }
+
///
/// Replaces the token manager by the specified type.
///
@@ -275,6 +344,29 @@ public sealed class OpenIddictCoreBuilder
return this;
}
+ ///
+ /// Replaces the token store by the specified type.
+ ///
+ ///
+ /// Note: the specified type MUST be an open generic type definition containing exactly one generic argument.
+ ///
+ /// The type of the store.
+ /// The lifetime of the store.
+ /// The instance.
+ public OpenIddictCoreBuilder ReplaceTokenStore(
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type type,
+ ServiceLifetime lifetime = ServiceLifetime.Scoped)
+ {
+ if (!type.IsGenericTypeDefinition || type.GetGenericArguments() is not { Length: 1 })
+ {
+ throw new ArgumentException(SR.GetResourceString(SR.ID0232), nameof(type));
+ }
+
+ Services.Replace(ServiceDescriptor.Describe(typeof(IOpenIddictTokenStore<>), type, lifetime));
+
+ return this;
+ }
+
///
/// Disables additional filtering so that the OpenIddict managers don't execute a second check
/// to ensure the results returned by the stores exactly match the specified query filters,