diff --git a/src/OpenIddict.EntityFramework/Configurations/OpenIddictApplicationConfiguration.cs b/src/OpenIddict.EntityFramework/Configurations/OpenIddictApplicationConfiguration.cs
new file mode 100644
index 00000000..3cb81bf3
--- /dev/null
+++ b/src/OpenIddict.EntityFramework/Configurations/OpenIddictApplicationConfiguration.cs
@@ -0,0 +1,72 @@
+/*
+ * 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;
+using System.ComponentModel;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.Data.Entity.Infrastructure.Annotations;
+using System.Data.Entity.ModelConfiguration;
+using System.Text;
+using OpenIddict.EntityFramework.Models;
+
+namespace OpenIddict.EntityFramework
+{
+ ///
+ /// Defines a relational mapping for the Application entity.
+ ///
+ /// The type of the Application entity.
+ /// The type of the Authorization entity.
+ /// The type of the Token entity.
+ /// The type of the Key entity.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public class OpenIddictApplicationConfiguration : EntityTypeConfiguration
+ where TApplication : OpenIddictApplication
+ where TAuthorization : OpenIddictAuthorization
+ where TToken : OpenIddictToken
+ where TKey : IEquatable
+ {
+ public OpenIddictApplicationConfiguration()
+ {
+ // Note: unlike Entity Framework Core 1.x/2.x, Entity Framework 6.x
+ // always throws an exception when using generic types as entity types.
+ // To ensure a better exception is thrown, a manual check is made here.
+ if (typeof(TApplication).IsGenericType)
+ {
+ throw new InvalidOperationException(new StringBuilder()
+ .AppendLine("The application entity cannot be a generic type.")
+ .Append("Consider creating a non-generic derived class.")
+ .ToString());
+ }
+
+ // Warning: optional foreign keys MUST NOT be added as CLR properties because
+ // Entity Framework would throw an exception due to the TKey generic parameter
+ // being non-nullable when using value types like short, int, long or Guid.
+
+ HasKey(application => application.Id);
+
+ Property(application => application.ClientId)
+ .IsRequired()
+ .HasMaxLength(450)
+ .HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation(new IndexAttribute()));
+
+ Property(application => application.ConcurrencyToken)
+ .IsConcurrencyToken();
+
+ Property(application => application.Type)
+ .IsRequired();
+
+ HasMany(application => application.Authorizations)
+ .WithOptional(authorization => authorization.Application)
+ .Map(association => association.MapKey("ApplicationId"));
+
+ HasMany(application => application.Tokens)
+ .WithOptional(token => token.Application)
+ .Map(association => association.MapKey("ApplicationId"));
+
+ ToTable("OpenIddictApplications");
+ }
+ }
+}
diff --git a/src/OpenIddict.EntityFramework/Configurations/OpenIddictAuthorizationConfiguration.cs b/src/OpenIddict.EntityFramework/Configurations/OpenIddictAuthorizationConfiguration.cs
new file mode 100644
index 00000000..6d30cc12
--- /dev/null
+++ b/src/OpenIddict.EntityFramework/Configurations/OpenIddictAuthorizationConfiguration.cs
@@ -0,0 +1,68 @@
+/*
+ * 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;
+using System.ComponentModel;
+using System.Data.Entity.ModelConfiguration;
+using System.Text;
+using OpenIddict.EntityFramework.Models;
+
+namespace OpenIddict.EntityFramework
+{
+ ///
+ /// Defines a relational mapping for the Authorization entity.
+ ///
+ /// The type of the Authorization entity.
+ /// The type of the Application entity.
+ /// The type of the Token entity.
+ /// The type of the Key entity.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public class OpenIddictAuthorizationConfiguration : EntityTypeConfiguration
+ where TAuthorization : OpenIddictAuthorization
+ where TApplication : OpenIddictApplication
+ where TToken : OpenIddictToken
+ where TKey : IEquatable
+ {
+ public OpenIddictAuthorizationConfiguration()
+ {
+ // Note: unlike Entity Framework Core 1.x/2.x, Entity Framework 6.x
+ // always throws an exception when using generic types as entity types.
+ // To ensure a better exception is thrown, a manual check is made here.
+ if (typeof(TAuthorization).IsGenericType)
+ {
+ throw new InvalidOperationException(new StringBuilder()
+ .AppendLine("The authorization entity cannot be a generic type.")
+ .Append("Consider creating a non-generic derived class.")
+ .ToString());
+ }
+
+ // Warning: optional foreign keys MUST NOT be added as CLR properties because
+ // Entity Framework would throw an exception due to the TKey generic parameter
+ // being non-nullable when using value types like short, int, long or Guid.
+
+ HasKey(authorization => authorization.Id);
+
+ Property(authorization => authorization.ConcurrencyToken)
+ .IsConcurrencyToken();
+
+ Property(authorization => authorization.Status)
+ .IsRequired();
+
+ Property(authorization => authorization.Subject)
+ .IsRequired();
+
+ Property(authorization => authorization.Type)
+ .IsRequired();
+
+ HasMany(authorization => authorization.Tokens)
+ .WithOptional(token => token.Authorization)
+ .Map(association => association.MapKey("AuthorizationId"))
+ .WillCascadeOnDelete();
+
+ ToTable("OpenIddictAuthorizations");
+ }
+ }
+}
diff --git a/src/OpenIddict.EntityFramework/Configurations/OpenIddictScopeConfiguration.cs b/src/OpenIddict.EntityFramework/Configurations/OpenIddictScopeConfiguration.cs
new file mode 100644
index 00000000..6748215f
--- /dev/null
+++ b/src/OpenIddict.EntityFramework/Configurations/OpenIddictScopeConfiguration.cs
@@ -0,0 +1,57 @@
+/*
+ * 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;
+using System.ComponentModel;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.Data.Entity.Infrastructure.Annotations;
+using System.Data.Entity.ModelConfiguration;
+using System.Text;
+using OpenIddict.EntityFramework.Models;
+
+namespace OpenIddict.EntityFramework
+{
+ ///
+ /// Defines a relational mapping for the Scope entity.
+ ///
+ /// The type of the Scope entity.
+ /// The type of the Key entity.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public class OpenIddictScopeConfiguration : EntityTypeConfiguration
+ where TScope : OpenIddictScope
+ where TKey : IEquatable
+ {
+ public OpenIddictScopeConfiguration()
+ {
+ // Note: unlike Entity Framework Core 1.x/2.x, Entity Framework 6.x
+ // always throws an exception when using generic types as entity types.
+ // To ensure a better exception is thrown, a manual check is made here.
+ if (typeof(TScope).IsGenericType)
+ {
+ throw new InvalidOperationException(new StringBuilder()
+ .AppendLine("The scope entity cannot be a generic type.")
+ .Append("Consider creating a non-generic derived class.")
+ .ToString());
+ }
+
+ // Warning: optional foreign keys MUST NOT be added as CLR properties because
+ // Entity Framework would throw an exception due to the TKey generic parameter
+ // being non-nullable when using value types like short, int, long or Guid.
+
+ HasKey(scope => scope.Id);
+
+ Property(scope => scope.ConcurrencyToken)
+ .IsConcurrencyToken();
+
+ Property(scope => scope.Name)
+ .IsRequired()
+ .HasMaxLength(450)
+ .HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation(new IndexAttribute()));
+
+ ToTable("OpenIddictScopes");
+ }
+ }
+}
diff --git a/src/OpenIddict.EntityFramework/Configurations/OpenIddictTokenConfiguration.cs b/src/OpenIddict.EntityFramework/Configurations/OpenIddictTokenConfiguration.cs
new file mode 100644
index 00000000..ef442392
--- /dev/null
+++ b/src/OpenIddict.EntityFramework/Configurations/OpenIddictTokenConfiguration.cs
@@ -0,0 +1,66 @@
+/*
+ * 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;
+using System.ComponentModel;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.Data.Entity.Infrastructure.Annotations;
+using System.Data.Entity.ModelConfiguration;
+using System.Text;
+using OpenIddict.EntityFramework.Models;
+
+namespace OpenIddict.EntityFramework
+{
+ ///
+ /// Defines a relational mapping for the Token entity.
+ ///
+ /// The type of the Token entity.
+ /// The type of the Application entity.
+ /// The type of the Authorization entity.
+ /// The type of the Key entity.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public class OpenIddictTokenConfiguration : EntityTypeConfiguration
+ where TToken : OpenIddictToken
+ where TApplication : OpenIddictApplication
+ where TAuthorization : OpenIddictAuthorization
+ where TKey : IEquatable
+ {
+ public OpenIddictTokenConfiguration()
+ {
+ // Note: unlike Entity Framework Core 1.x/2.x, Entity Framework 6.x
+ // always throws an exception when using generic types as entity types.
+ // To ensure a better exception is thrown, a manual check is made here.
+ if (typeof(TToken).IsGenericType)
+ {
+ throw new InvalidOperationException(new StringBuilder()
+ .AppendLine("The token entity cannot be a generic type.")
+ .Append("Consider creating a non-generic derived class.")
+ .ToString());
+ }
+
+ // Warning: optional foreign keys MUST NOT be added as CLR properties because
+ // Entity Framework would throw an exception due to the TKey generic parameter
+ // being non-nullable when using value types like short, int, long or Guid.
+
+ HasKey(token => token.Id);
+
+ Property(token => token.ConcurrencyToken)
+ .IsConcurrencyToken();
+
+ Property(token => token.ReferenceId)
+ .HasMaxLength(450)
+ .HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation(new IndexAttribute()));
+
+ Property(token => token.Subject)
+ .IsRequired();
+
+ Property(token => token.Type)
+ .IsRequired();
+
+ ToTable("OpenIddictTokens");
+ }
+ }
+}
diff --git a/src/OpenIddict.EntityFramework/OpenIddictEntityFrameworkExtensions.cs b/src/OpenIddict.EntityFramework/OpenIddictEntityFrameworkExtensions.cs
index d6833a88..c5225680 100644
--- a/src/OpenIddict.EntityFramework/OpenIddictEntityFrameworkExtensions.cs
+++ b/src/OpenIddict.EntityFramework/OpenIddictEntityFrameworkExtensions.cs
@@ -5,10 +5,7 @@
*/
using System;
-using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
-using System.Data.Entity.Infrastructure.Annotations;
-using System.Text;
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection.Extensions;
using OpenIddict.EntityFramework;
@@ -80,7 +77,7 @@ namespace Microsoft.Extensions.DependencyInjection
}
///
- /// Registers the OpenIddict entity sets in the Entity Framework context
+ /// Registers the OpenIddict entity sets in the Entity Framework 6.x context
/// using the default OpenIddict models and the default key type (string).
///
/// The builder used to configure the Entity Framework context.
@@ -92,8 +89,8 @@ namespace Microsoft.Extensions.DependencyInjection
OpenIddictToken, string>();
///
- /// Registers the OpenIddict entity sets in the Entity Framework context
- /// using the specified entities and the specified key type.
+ /// Registers the OpenIddict entity sets in the Entity Framework 6.x
+ /// context using the specified entities and the specified key type.
/// Note: using this method requires creating non-generic derived classes
/// for all the OpenIddict entities (application, authorization, scope, token).
///
@@ -111,145 +108,10 @@ namespace Microsoft.Extensions.DependencyInjection
throw new ArgumentNullException(nameof(builder));
}
- // Note: unlike Entity Framework 6.x 1.x/2.x, Entity Framework 6.x
- // always throws an exception when using generic types as entity types.
- // To ensure a better exception is thrown, a manual check is made here.
- if (typeof(TApplication).IsGenericType)
- {
- throw new InvalidOperationException(new StringBuilder()
- .AppendLine("The application entity cannot be a generic type.")
- .Append("Consider creating a non-generic derived class.")
- .ToString());
- }
-
- if (typeof(TAuthorization).IsGenericType)
- {
- throw new InvalidOperationException(new StringBuilder()
- .AppendLine("The authorization entity cannot be a generic type.")
- .Append("Consider creating a non-generic derived class.")
- .ToString());
- }
-
- if (typeof(TScope).IsGenericType)
- {
- throw new InvalidOperationException(new StringBuilder()
- .AppendLine("The scope entity cannot be a generic type.")
- .Append("Consider creating a non-generic derived class.")
- .ToString());
- }
-
- if (typeof(TToken).IsGenericType)
- {
- throw new InvalidOperationException(new StringBuilder()
- .AppendLine("The token entity cannot be a generic type.")
- .Append("Consider creating a non-generic derived class.")
- .ToString());
- }
-
- // Warning: optional foreign keys MUST NOT be added as CLR properties because
- // Entity Framework would throw an exception due to the TKey generic parameter
- // being non-nullable when using value types like short, int, long or Guid.
-
- // Configure the TApplication entity.
- builder.Entity()
- .HasKey(application => application.Id);
-
- builder.Entity()
- .Property(application => application.ClientId)
- .IsRequired()
- .HasMaxLength(450)
- .HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation(new IndexAttribute()));
-
- builder.Entity()
- .Property(application => application.ConcurrencyToken)
- .IsConcurrencyToken();
-
- builder.Entity()
- .Property(application => application.Type)
- .IsRequired();
-
- builder.Entity()
- .HasMany(application => application.Authorizations)
- .WithOptional(authorization => authorization.Application)
- .Map(association => association.MapKey("ApplicationId"));
-
- builder.Entity()
- .HasMany(application => application.Tokens)
- .WithOptional(token => token.Application)
- .Map(association => association.MapKey("ApplicationId"));
-
- builder.Entity()
- .ToTable("OpenIddictApplications");
-
- // Configure the TAuthorization entity.
- builder.Entity()
- .HasKey(authorization => authorization.Id);
-
- builder.Entity()
- .Property(authorization => authorization.ConcurrencyToken)
- .IsConcurrencyToken();
-
- builder.Entity()
- .Property(authorization => authorization.Status)
- .IsRequired();
-
- builder.Entity()
- .Property(authorization => authorization.Subject)
- .IsRequired();
-
- builder.Entity()
- .Property(authorization => authorization.Type)
- .IsRequired();
-
- builder.Entity()
- .HasMany(application => application.Tokens)
- .WithOptional(token => token.Authorization)
- .Map(association => association.MapKey("AuthorizationId"))
- .WillCascadeOnDelete();
-
- builder.Entity()
- .ToTable("OpenIddictAuthorizations");
-
- // Configure the TScope entity.
- builder.Entity()
- .HasKey(scope => scope.Id);
-
- builder.Entity()
- .Property(scope => scope.ConcurrencyToken)
- .IsConcurrencyToken();
-
- builder.Entity()
- .Property(scope => scope.Name)
- .IsRequired()
- .HasMaxLength(450)
- .HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation(new IndexAttribute()));
-
- builder.Entity()
- .ToTable("OpenIddictScopes");
-
- // Configure the TToken entity.
- builder.Entity()
- .HasKey(token => token.Id);
-
- builder.Entity()
- .Property(token => token.ConcurrencyToken)
- .IsConcurrencyToken();
-
- builder.Entity()
- .Property(token => token.ReferenceId)
- .HasMaxLength(450)
- .HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation(new IndexAttribute()));
-
- builder.Entity()
- .Property(token => token.Subject)
- .IsRequired();
-
- builder.Entity()
- .Property(token => token.Type)
- .IsRequired();
-
- builder.Entity()
- .ToTable("OpenIddictTokens");
+ builder.Configurations.Add(new OpenIddictApplicationConfiguration());
+ builder.Configurations.Add(new OpenIddictAuthorizationConfiguration());
+ builder.Configurations.Add(new OpenIddictScopeConfiguration());
+ builder.Configurations.Add(new OpenIddictTokenConfiguration());
return builder;
}
diff --git a/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictApplicationConfiguration.cs b/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictApplicationConfiguration.cs
new file mode 100644
index 00000000..5c96953c
--- /dev/null
+++ b/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictApplicationConfiguration.cs
@@ -0,0 +1,67 @@
+/*
+ * 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;
+using System.ComponentModel;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+using OpenIddict.EntityFrameworkCore.Models;
+
+namespace OpenIddict.EntityFrameworkCore
+{
+ ///
+ /// Defines a relational mapping for the Application entity.
+ ///
+ /// The type of the Application entity.
+ /// The type of the Authorization entity.
+ /// The type of the Token entity.
+ /// The type of the Key entity.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public class OpenIddictApplicationConfiguration : IEntityTypeConfiguration
+ where TApplication : OpenIddictApplication
+ where TAuthorization : OpenIddictAuthorization
+ where TToken : OpenIddictToken
+ where TKey : IEquatable
+ {
+ public void Configure(EntityTypeBuilder builder)
+ {
+ if (builder == null)
+ {
+ throw new ArgumentNullException(nameof(builder));
+ }
+
+ // Warning: optional foreign keys MUST NOT be added as CLR properties because
+ // Entity Framework would throw an exception due to the TKey generic parameter
+ // being non-nullable when using value types like short, int, long or Guid.
+
+ builder.HasKey(application => application.Id);
+
+ builder.HasIndex(application => application.ClientId)
+ .IsUnique();
+
+ builder.Property(application => application.ClientId)
+ .IsRequired();
+
+ builder.Property(application => application.ConcurrencyToken)
+ .IsConcurrencyToken();
+
+ builder.Property(application => application.Type)
+ .IsRequired();
+
+ builder.HasMany(application => application.Authorizations)
+ .WithOne(authorization => authorization.Application)
+ .HasForeignKey("ApplicationId")
+ .IsRequired(required: false);
+
+ builder.HasMany(application => application.Tokens)
+ .WithOne(token => token.Application)
+ .HasForeignKey("ApplicationId")
+ .IsRequired(required: false);
+
+ builder.ToTable("OpenIddictApplications");
+ }
+ }
+}
diff --git a/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictAuthorizationConfiguration.cs b/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictAuthorizationConfiguration.cs
new file mode 100644
index 00000000..f78a5292
--- /dev/null
+++ b/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictAuthorizationConfiguration.cs
@@ -0,0 +1,62 @@
+/*
+ * 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;
+using System.ComponentModel;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+using OpenIddict.EntityFrameworkCore.Models;
+
+namespace OpenIddict.EntityFrameworkCore
+{
+ ///
+ /// Defines a relational mapping for the Authorization entity.
+ ///
+ /// The type of the Authorization entity.
+ /// The type of the Application entity.
+ /// The type of the Token entity.
+ /// The type of the Key entity.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public class OpenIddictAuthorizationConfiguration : IEntityTypeConfiguration
+ where TAuthorization : OpenIddictAuthorization
+ where TApplication : OpenIddictApplication
+ where TToken : OpenIddictToken
+ where TKey : IEquatable
+ {
+ public void Configure(EntityTypeBuilder builder)
+ {
+ if (builder == null)
+ {
+ throw new ArgumentNullException(nameof(builder));
+ }
+
+ // Warning: optional foreign keys MUST NOT be added as CLR properties because
+ // Entity Framework would throw an exception due to the TKey generic parameter
+ // being non-nullable when using value types like short, int, long or Guid.
+
+ builder.HasKey(authorization => authorization.Id);
+
+ builder.Property(authorization => authorization.ConcurrencyToken)
+ .IsConcurrencyToken();
+
+ builder.Property(authorization => authorization.Status)
+ .IsRequired();
+
+ builder.Property(authorization => authorization.Subject)
+ .IsRequired();
+
+ builder.Property(authorization => authorization.Type)
+ .IsRequired();
+
+ builder.HasMany(authorization => authorization.Tokens)
+ .WithOne(token => token.Authorization)
+ .HasForeignKey("AuthorizationId")
+ .IsRequired(required: false);
+
+ builder.ToTable("OpenIddictAuthorizations");
+ }
+ }
+}
diff --git a/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictScopeConfiguration.cs b/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictScopeConfiguration.cs
new file mode 100644
index 00000000..d76c220f
--- /dev/null
+++ b/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictScopeConfiguration.cs
@@ -0,0 +1,50 @@
+/*
+ * 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;
+using System.ComponentModel;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+using OpenIddict.EntityFrameworkCore.Models;
+
+namespace OpenIddict.EntityFrameworkCore
+{
+ ///
+ /// Defines a relational mapping for the Scope entity.
+ ///
+ /// The type of the Scope entity.
+ /// The type of the Key entity.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public class OpenIddictScopeConfiguration : IEntityTypeConfiguration
+ where TScope : OpenIddictScope
+ where TKey : IEquatable
+ {
+ public void Configure(EntityTypeBuilder builder)
+ {
+ if (builder == null)
+ {
+ throw new ArgumentNullException(nameof(builder));
+ }
+
+ // Warning: optional foreign keys MUST NOT be added as CLR properties because
+ // Entity Framework would throw an exception due to the TKey generic parameter
+ // being non-nullable when using value types like short, int, long or Guid.
+
+ builder.HasKey(scope => scope.Id);
+
+ builder.HasIndex(scope => scope.Name)
+ .IsUnique();
+
+ builder.Property(scope => scope.ConcurrencyToken)
+ .IsConcurrencyToken();
+
+ builder.Property(scope => scope.Name)
+ .IsRequired();
+
+ builder.ToTable("OpenIddictScopes");
+ }
+ }
+}
diff --git a/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictTokenConfiguration.cs b/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictTokenConfiguration.cs
new file mode 100644
index 00000000..c3665e70
--- /dev/null
+++ b/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictTokenConfiguration.cs
@@ -0,0 +1,57 @@
+/*
+ * 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;
+using System.ComponentModel;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+using OpenIddict.EntityFrameworkCore.Models;
+
+namespace OpenIddict.EntityFrameworkCore
+{
+ ///
+ /// Defines a relational mapping for the Token entity.
+ ///
+ /// The type of the Token entity.
+ /// The type of the Application entity.
+ /// The type of the Authorization entity.
+ /// The type of the Key entity.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public class OpenIddictTokenConfiguration : IEntityTypeConfiguration
+ where TToken : OpenIddictToken
+ where TApplication : OpenIddictApplication
+ where TAuthorization : OpenIddictAuthorization
+ where TKey : IEquatable
+ {
+ public void Configure(EntityTypeBuilder builder)
+ {
+ if (builder == null)
+ {
+ throw new ArgumentNullException(nameof(builder));
+ }
+
+ // Warning: optional foreign keys MUST NOT be added as CLR properties because
+ // Entity Framework would throw an exception due to the TKey generic parameter
+ // being non-nullable when using value types like short, int, long or Guid.
+
+ builder.HasKey(token => token.Id);
+
+ builder.HasIndex(token => token.ReferenceId)
+ .IsUnique();
+
+ builder.Property(token => token.ConcurrencyToken)
+ .IsConcurrencyToken();
+
+ builder.Property(token => token.Subject)
+ .IsRequired();
+
+ builder.Property(token => token.Type)
+ .IsRequired();
+
+ builder.ToTable("OpenIddictTokens");
+ }
+ }
+}
diff --git a/src/OpenIddict.EntityFrameworkCore/OpenIddictEntityFrameworkCoreCustomizer.cs b/src/OpenIddict.EntityFrameworkCore/OpenIddictEntityFrameworkCoreCustomizer.cs
index e254dac5..c5e528bb 100644
--- a/src/OpenIddict.EntityFrameworkCore/OpenIddictEntityFrameworkCoreCustomizer.cs
+++ b/src/OpenIddict.EntityFrameworkCore/OpenIddictEntityFrameworkCoreCustomizer.cs
@@ -15,7 +15,7 @@ namespace OpenIddict.EntityFrameworkCore
{
///
/// Represents a model customizer able to register the entity sets
- /// required by the OpenIddict stack in an Entity Framework context.
+ /// required by the OpenIddict stack in an Entity Framework Core context.
///
public class OpenIddictEntityFrameworkCoreCustomizer : RelationalModelCustomizer
where TApplication : OpenIddictApplication
diff --git a/src/OpenIddict.EntityFrameworkCore/OpenIddictEntityFrameworkCoreExtensions.cs b/src/OpenIddict.EntityFrameworkCore/OpenIddictEntityFrameworkCoreExtensions.cs
index 1cc2b553..8471b07e 100644
--- a/src/OpenIddict.EntityFrameworkCore/OpenIddictEntityFrameworkCoreExtensions.cs
+++ b/src/OpenIddict.EntityFrameworkCore/OpenIddictEntityFrameworkCoreExtensions.cs
@@ -78,7 +78,7 @@ namespace Microsoft.Extensions.DependencyInjection
}
///
- /// Registers the OpenIddict entity sets in the Entity Framework context
+ /// Registers the OpenIddict entity sets in the Entity Framework Core context
/// using the default OpenIddict models and the default key type (string).
///
/// The builder used to configure the Entity Framework context.
@@ -90,8 +90,8 @@ namespace Microsoft.Extensions.DependencyInjection
OpenIddictToken, string>();
///
- /// Registers the OpenIddict entity sets in the Entity Framework context
- /// using the default OpenIddict models and the specified key type.
+ /// Registers the OpenIddict entity sets in the Entity Framework Core
+ /// context using the default OpenIddict models and the specified key type.
///
/// The builder used to configure the Entity Framework context.
/// The Entity Framework context builder.
@@ -103,8 +103,8 @@ namespace Microsoft.Extensions.DependencyInjection
OpenIddictToken, TKey>();
///
- /// Registers the OpenIddict entity sets in the Entity Framework context
- /// using the specified entities and the specified key type.
+ /// Registers the OpenIddict entity sets in the Entity Framework Core
+ /// context using the specified entities and the specified key type.
///
/// The builder used to configure the Entity Framework context.
/// The Entity Framework context builder.
@@ -125,7 +125,7 @@ namespace Microsoft.Extensions.DependencyInjection
}
///
- /// Registers the OpenIddict entity sets in the Entity Framework context
+ /// Registers the OpenIddict entity sets in the Entity Framework Core context
/// using the default OpenIddict models and the default key type (string).
///
/// The builder used to configure the Entity Framework context.
@@ -137,8 +137,8 @@ namespace Microsoft.Extensions.DependencyInjection
OpenIddictToken, string>();
///
- /// Registers the OpenIddict entity sets in the Entity Framework context
- /// using the default OpenIddict models and the specified key type.
+ /// Registers the OpenIddict entity sets in the Entity Framework Core
+ /// context using the default OpenIddict models and the specified key type.
///
/// The builder used to configure the Entity Framework context.
/// The Entity Framework context builder.
@@ -149,8 +149,8 @@ namespace Microsoft.Extensions.DependencyInjection
OpenIddictToken, TKey>();
///
- /// Registers the OpenIddict entity sets in the Entity Framework context
- /// using the specified entities and the specified key type.
+ /// Registers the OpenIddict entity sets in the Entity Framework Core
+ /// context using the specified entities and the specified key type.
///
/// The builder used to configure the Entity Framework context.
/// The Entity Framework context builder.
@@ -166,101 +166,10 @@ namespace Microsoft.Extensions.DependencyInjection
throw new ArgumentNullException(nameof(builder));
}
- // Warning: optional foreign keys MUST NOT be added as CLR properties because
- // Entity Framework would throw an exception due to the TKey generic parameter
- // being non-nullable when using value types like short, int, long or Guid.
-
- // Configure the TApplication entity.
- builder.Entity(entity =>
- {
- entity.HasKey(application => application.Id);
-
- entity.HasIndex(application => application.ClientId)
- .IsUnique();
-
- entity.Property(application => application.ClientId)
- .IsRequired();
-
- entity.Property(application => application.ConcurrencyToken)
- .IsConcurrencyToken();
-
- entity.Property(application => application.Type)
- .IsRequired();
-
- entity.HasMany(application => application.Authorizations)
- .WithOne(authorization => authorization.Application)
- .HasForeignKey("ApplicationId")
- .IsRequired(required: false);
-
- entity.HasMany(application => application.Tokens)
- .WithOne(token => token.Application)
- .HasForeignKey("ApplicationId")
- .IsRequired(required: false);
-
- entity.ToTable("OpenIddictApplications");
- });
-
- // Configure the TAuthorization entity.
- builder.Entity(entity =>
- {
- entity.HasKey(authorization => authorization.Id);
-
- entity.Property(authorization => authorization.ConcurrencyToken)
- .IsConcurrencyToken();
-
- entity.Property(authorization => authorization.Status)
- .IsRequired();
-
- entity.Property(authorization => authorization.Subject)
- .IsRequired();
-
- entity.Property(authorization => authorization.Type)
- .IsRequired();
-
- entity.HasMany(authorization => authorization.Tokens)
- .WithOne(token => token.Authorization)
- .HasForeignKey("AuthorizationId")
- .IsRequired(required: false);
-
- entity.ToTable("OpenIddictAuthorizations");
- });
-
- // Configure the TScope entity.
- builder.Entity(entity =>
- {
- entity.HasKey(scope => scope.Id);
-
- entity.HasIndex(scope => scope.Name)
- .IsUnique();
-
- entity.Property(scope => scope.ConcurrencyToken)
- .IsConcurrencyToken();
-
- entity.Property(scope => scope.Name)
- .IsRequired();
-
- entity.ToTable("OpenIddictScopes");
- });
-
- // Configure the TToken entity.
- builder.Entity(entity =>
- {
- entity.HasKey(token => token.Id);
-
- entity.HasIndex(token => token.ReferenceId)
- .IsUnique();
-
- entity.Property(token => token.ConcurrencyToken)
- .IsConcurrencyToken();
-
- entity.Property(token => token.Subject)
- .IsRequired();
-
- entity.Property(token => token.Type)
- .IsRequired();
-
- entity.ToTable("OpenIddictTokens");
- });
+ builder.ApplyConfiguration(new OpenIddictApplicationConfiguration());
+ builder.ApplyConfiguration(new OpenIddictAuthorizationConfiguration());
+ builder.ApplyConfiguration(new OpenIddictScopeConfiguration());
+ builder.ApplyConfiguration(new OpenIddictTokenConfiguration());
return builder;
}
diff --git a/test/OpenIddict.EntityFrameworkCore.Tests/OpenIddictEntityFrameworkCoreExtensionsTests.cs b/test/OpenIddict.EntityFrameworkCore.Tests/OpenIddictEntityFrameworkCoreExtensionsTests.cs
index 1ce3e2e0..7d362a8a 100644
--- a/test/OpenIddict.EntityFrameworkCore.Tests/OpenIddictEntityFrameworkCoreExtensionsTests.cs
+++ b/test/OpenIddict.EntityFrameworkCore.Tests/OpenIddictEntityFrameworkCoreExtensionsTests.cs
@@ -5,9 +5,12 @@
*/
using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Conventions;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
+using Moq;
using OpenIddict.Abstractions;
using OpenIddict.Core;
using OpenIddict.EntityFrameworkCore.Models;
@@ -112,5 +115,70 @@ namespace OpenIddict.EntityFrameworkCore.Tests
// Assert
Assert.Contains(services, service => service.ServiceType == type && service.ImplementationType == type);
}
+
+ [Fact]
+ public void UseOpenIddict_RegistersDefaultEntityConfigurations()
+ {
+ // Arrange
+ var builder = new Mock(new ConventionSet());
+
+ // Act
+ builder.Object.UseOpenIddict();
+
+ // Assert
+ builder.Verify(mock => mock.ApplyConfiguration(
+ It.IsAny>()), Times.Once());
+ builder.Verify(mock => mock.ApplyConfiguration(
+ It.IsAny>()), Times.Once());
+ builder.Verify(mock => mock.ApplyConfiguration(
+ It.IsAny>()), Times.Once());
+ builder.Verify(mock => mock.ApplyConfiguration(
+ It.IsAny>()), Times.Once());
+ }
+
+ [Fact]
+ public void UseOpenIddict_RegistersDefaultEntityConfigurationsWithCustomKeyType()
+ {
+ // Arrange
+ var builder = new Mock(new ConventionSet());
+
+ // Act
+ builder.Object.UseOpenIddict();
+
+ // Assert
+ builder.Verify(mock => mock.ApplyConfiguration(
+ It.IsAny, OpenIddictAuthorization, OpenIddictToken, long>>()), Times.Once());
+ builder.Verify(mock => mock.ApplyConfiguration(
+ It.IsAny, OpenIddictApplication, OpenIddictToken, long>>()), Times.Once());
+ builder.Verify(mock => mock.ApplyConfiguration(
+ It.IsAny, long>>()), Times.Once());
+ builder.Verify(mock => mock.ApplyConfiguration(
+ It.IsAny, OpenIddictApplication, OpenIddictAuthorization, long>>()), Times.Once());
+ }
+
+ [Fact]
+ public void UseOpenIddict_RegistersCustomEntityConfigurations()
+ {
+ // Arrange
+ var builder = new Mock(new ConventionSet());
+
+ // Act
+ builder.Object.UseOpenIddict();
+
+ // Assert
+ builder.Verify(mock => mock.ApplyConfiguration(
+ It.IsAny>()), Times.Once());
+ builder.Verify(mock => mock.ApplyConfiguration(
+ It.IsAny>()), Times.Once());
+ builder.Verify(mock => mock.ApplyConfiguration(
+ It.IsAny>()), Times.Once());
+ builder.Verify(mock => mock.ApplyConfiguration(
+ It.IsAny>()), Times.Once());
+ }
+
+ public class CustomApplication : OpenIddictApplication { }
+ public class CustomAuthorization : OpenIddictAuthorization { }
+ public class CustomScope : OpenIddictScope { }
+ public class CustomToken : OpenIddictToken { }
}
}