Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// ReactiveUI Association Incorporated licenses this file to you under the MIT license.
// See the LICENSE file in the project root for full license information.

using System.Diagnostics.CodeAnalysis;

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
Expand All @@ -24,6 +26,119 @@ public static class HostBuilderEntityFrameworkCoreExtensions
/// <param name="builder">The receiver instance.</param>
extension(IHostApplicationBuilder builder)
{
/// <summary>Configures Entity Framework Core with SQLite and ASP.NET Core Identity using IHostApplicationBuilder.</summary>
/// <remarks>This method provides integration with the modern IHostApplicationBuilder pattern and
/// sets up both Entity Framework Core and ASP.NET Core Identity with the specified user and role types.</remarks>
/// <typeparam name="TContext">The type of the Entity Framework Core DbContext to use for data access.</typeparam>
/// <typeparam name="TUser">The type representing application users for ASP.NET Core Identity.</typeparam>
/// <typeparam name="TRole">The type representing application roles for ASP.NET Core Identity.</typeparam>
/// <param name="connectionStringName">The name of the connection string in the configuration. Cannot be null or whitespace.</param>
/// <returns>The same IHostApplicationBuilder instance so that additional calls can be chained.</returns>
[SuppressMessage(
"Design",
"SST2307",
Justification = "Explicit Identity types preserve the public overload signatures released in version 4.1.0.")]
public IHostApplicationBuilder AddSqliteWithIdentity<
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TContext,
TUser,
TRole>(string connectionStringName)
where TContext : DbContext
where TUser : class
where TRole : class =>
builder.AddSqliteWithIdentity<TContext, TUser, TRole>(connectionStringName, ServiceLifetime.Scoped);

/// <summary>Configures SQLite and Identity with an explicit service lifetime.</summary>
/// <typeparam name="TContext">The Entity Framework Core DbContext type.</typeparam>
/// <typeparam name="TUser">The Identity user type.</typeparam>
/// <typeparam name="TRole">The Identity role type.</typeparam>
/// <param name="connectionStringName">The configured connection string name.</param>
/// <param name="serviceLifetime">The lifetime with which to register the DbContext service.</param>
/// <returns>The same IHostApplicationBuilder instance so that additional calls can be chained.</returns>
/// <exception cref="ArgumentException">Thrown if connectionStringName is null or consists only of white-space characters.</exception>
/// <exception cref="InvalidOperationException">Thrown if the specified connection string is not found in the configuration.</exception>
[SuppressMessage(
"Design",
"SST2307",
Justification = "Explicit Identity types preserve the public overload signatures released in version 4.1.0.")]
public IHostApplicationBuilder AddSqliteWithIdentity<
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TContext,
TUser,
TRole>(
string connectionStringName,
ServiceLifetime serviceLifetime)
where TContext : DbContext
where TUser : class
where TRole : class
{
_ = builder ?? throw new ArgumentNullException(nameof(builder));

ArgumentException.ThrowIfNullOrWhiteSpace(connectionStringName);

var conString = builder.Configuration.GetConnectionString(connectionStringName);
_ = builder.Services
.AddDbContext<TContext>(
options => options.UseSqlite(conString ?? throw new InvalidOperationException($"Connection string '{connectionStringName}' not found.")),
serviceLifetime,
serviceLifetime == ServiceLifetime.Singleton ? ServiceLifetime.Singleton : ServiceLifetime.Scoped)
.AddDefaultIdentity<TUser>()
.AddRoles<TRole>()
.AddEntityFrameworkStores<TContext>();
return builder;
}

/// <summary>Configures Entity Framework Core with SQLite and ASP.NET Core Identity (user only) using IHostApplicationBuilder.</summary>
/// <remarks>This method provides integration with the modern IHostApplicationBuilder pattern and
/// sets up both Entity Framework Core and ASP.NET Core Identity with the specified user type only.</remarks>
/// <typeparam name="TContext">The type of the Entity Framework Core DbContext to use for data access.</typeparam>
/// <typeparam name="TUser">The type representing application users for ASP.NET Core Identity.</typeparam>
/// <param name="connectionStringName">The name of the connection string in the configuration. Cannot be null or whitespace.</param>
/// <returns>The same IHostApplicationBuilder instance so that additional calls can be chained.</returns>
[SuppressMessage(
"Design",
"SST2307",
Justification = "Explicit Identity types preserve the public overload signatures released in version 4.1.0.")]
public IHostApplicationBuilder AddSqliteWithIdentity<
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TContext,
TUser>(string connectionStringName)
where TContext : DbContext
where TUser : class =>
builder.AddSqliteWithIdentity<TContext, TUser>(connectionStringName, ServiceLifetime.Scoped);

/// <summary>Configures SQLite and user-only Identity with an explicit service lifetime.</summary>
/// <typeparam name="TContext">The Entity Framework Core DbContext type.</typeparam>
/// <typeparam name="TUser">The Identity user type.</typeparam>
/// <param name="connectionStringName">The configured connection string name.</param>
/// <param name="serviceLifetime">The lifetime with which to register the DbContext service.</param>
/// <returns>The same IHostApplicationBuilder instance so that additional calls can be chained.</returns>
/// <exception cref="ArgumentException">Thrown if connectionStringName is null or consists only of white-space characters.</exception>
/// <exception cref="InvalidOperationException">Thrown if the specified connection string is not found in the configuration.</exception>
[SuppressMessage(
"Design",
"SST2307",
Justification = "Explicit Identity types preserve the public overload signatures released in version 4.1.0.")]
public IHostApplicationBuilder AddSqliteWithIdentity<
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TContext,
TUser>(
string connectionStringName,
ServiceLifetime serviceLifetime)
where TContext : DbContext
where TUser : class
{
_ = builder ?? throw new ArgumentNullException(nameof(builder));

ArgumentException.ThrowIfNullOrWhiteSpace(connectionStringName);

var conString = builder.Configuration.GetConnectionString(connectionStringName);
_ = builder.Services
.AddDbContext<TContext>(
options => options.UseSqlite(conString ?? throw new InvalidOperationException($"Connection string '{connectionStringName}' not found.")),
serviceLifetime,
serviceLifetime == ServiceLifetime.Singleton ? ServiceLifetime.Singleton : ServiceLifetime.Scoped)
.AddDefaultIdentity<TUser>()
.AddEntityFrameworkStores<TContext>();
return builder;
}

/// <summary>Configures Entity Framework Core with SQLite using the IHostApplicationBuilder pattern.</summary>
/// <remarks>This method provides integration with the modern IHostApplicationBuilder pattern
/// introduced in .NET 7+. It registers the DbContext with SQLite using the connection string
Expand Down Expand Up @@ -220,6 +335,142 @@ public IHostBuilder UseWebHostServices(
/// <param name="services">The receiver instance.</param>
extension(IServiceCollection services)
{
/// <summary>Configures Entity Framework Core with a SQLite provider and sets up ASP.NET Core Identity using the specified context, user, and role types.</summary>
/// <remarks>This method registers the DbContext with the SQLite provider and configures ASP.NET Core
/// Identity to use the specified user and role types with Entity Framework Core stores. It is typically called
/// during application startup to enable authentication and authorization using SQLite as the backing
/// store.</remarks>
/// <typeparam name="TContext">The type of the Entity Framework Core DbContext to use for data access.</typeparam>
/// <typeparam name="TUser">The type representing application users for ASP.NET Core Identity.</typeparam>
/// <typeparam name="TRole">The type representing application roles for ASP.NET Core Identity.</typeparam>
/// <param name="context">The web host builder context containing configuration and environment information. Cannot be null.</param>
/// <param name="connectionStringName">The name of the connection string in the configuration to use for the SQLite database. Cannot be null or
/// whitespace.</param>
/// <returns>The same IServiceCollection instance so that additional calls can be chained.</returns>
[SuppressMessage(
"Design",
"SST2307",
Justification = "Explicit Identity types preserve the public overload signatures released in version 4.1.0.")]
public IServiceCollection UseEntityFrameworkCoreSqlite<
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TContext,
TUser,
TRole>(
WebHostBuilderContext context,
string connectionStringName)
where TContext : DbContext
where TUser : class
where TRole : class =>
services.UseEntityFrameworkCoreSqlite<TContext, TUser, TRole>(
context,
connectionStringName,
ServiceLifetime.Scoped);

/// <summary>Configures SQLite and Identity with an explicit service lifetime.</summary>
/// <typeparam name="TContext">The Entity Framework Core DbContext type.</typeparam>
/// <typeparam name="TUser">The Identity user type.</typeparam>
/// <typeparam name="TRole">The Identity role type.</typeparam>
/// <param name="context">The web host builder context.</param>
/// <param name="connectionStringName">The configured connection string name.</param>
/// <param name="serviceLifetime">The lifetime with which to register the DbContext service.</param>
/// <returns>The same IServiceCollection instance so that additional calls can be chained.</returns>
/// <exception cref="ArgumentException">Thrown if connectionStringName is null or consists only of white-space characters.</exception>
/// <exception cref="InvalidOperationException">Thrown if the specified connection string is not found in the configuration.</exception>
[SuppressMessage(
"Design",
"SST2307",
Justification = "Explicit Identity types preserve the public overload signatures released in version 4.1.0.")]
public IServiceCollection UseEntityFrameworkCoreSqlite<
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TContext,
TUser,
TRole>(
WebHostBuilderContext context,
string connectionStringName,
ServiceLifetime serviceLifetime)
where TContext : DbContext
where TUser : class
where TRole : class
{
_ = services ?? throw new ArgumentNullException(nameof(services));
_ = context ?? throw new ArgumentNullException(nameof(context));

ArgumentException.ThrowIfNullOrWhiteSpace(connectionStringName);

var conString = context.Configuration.GetConnectionString(connectionStringName);
_ = services
.AddDbContext<TContext>(
options => options.UseSqlite(conString ?? throw new InvalidOperationException($"Connection string '{connectionStringName}' not found.")),
serviceLifetime,
serviceLifetime == ServiceLifetime.Singleton ? ServiceLifetime.Singleton : ServiceLifetime.Scoped)
.AddDefaultIdentity<TUser>()
.AddRoles<TRole>()
.AddEntityFrameworkStores<TContext>();
return services;
}

/// <summary>Configures Entity Framework Core with a SQLite provider and ASP.NET Core Identity using the specified DbContext and user type.</summary>
/// <remarks>This method registers the specified DbContext with a SQLite provider and configures ASP.NET
/// Core Identity to use Entity Framework Core stores. It is typically called during application startup to enable
/// authentication and data access using SQLite.</remarks>
/// <typeparam name="TContext">The type of the DbContext to use for Entity Framework Core operations.</typeparam>
/// <typeparam name="TUser">The type representing the user entity for ASP.NET Core Identity.</typeparam>
/// <param name="context">The WebHostBuilderContext containing application configuration and environment information.</param>
/// <param name="connectionStringName">The name of the connection string in the configuration to use for the SQLite database. Cannot be null or
/// whitespace.</param>
/// <returns>The IServiceCollection instance configured for SQLite and Identity.</returns>
[SuppressMessage(
"Design",
"SST2307",
Justification = "Explicit Identity types preserve the public overload signatures released in version 4.1.0.")]
public IServiceCollection UseEntityFrameworkCoreSqlite<
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TContext,
TUser>(
WebHostBuilderContext context,
string connectionStringName)
where TContext : DbContext
where TUser : class =>
services.UseEntityFrameworkCoreSqlite<TContext, TUser>(
context,
connectionStringName,
ServiceLifetime.Scoped);

/// <summary>Configures SQLite and user-only Identity with an explicit service lifetime.</summary>
/// <typeparam name="TContext">The Entity Framework Core DbContext type.</typeparam>
/// <typeparam name="TUser">The Identity user type.</typeparam>
/// <param name="context">The web host builder context.</param>
/// <param name="connectionStringName">The configured connection string name.</param>
/// <param name="serviceLifetime">The lifetime with which to register the DbContext service.</param>
/// <returns>The IServiceCollection instance with Entity Framework Core and Identity services configured for SQLite.</returns>
/// <exception cref="ArgumentException">Thrown if connectionStringName is null or consists only of white-space characters.</exception>
/// <exception cref="InvalidOperationException">Thrown if the specified connection string is not found in the configuration.</exception>
[SuppressMessage(
"Design",
"SST2307",
Justification = "Explicit Identity types preserve the public overload signatures released in version 4.1.0.")]
public IServiceCollection UseEntityFrameworkCoreSqlite<
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TContext,
TUser>(
WebHostBuilderContext context,
string connectionStringName,
ServiceLifetime serviceLifetime)
where TContext : DbContext
where TUser : class
{
_ = services ?? throw new ArgumentNullException(nameof(services));
_ = context ?? throw new ArgumentNullException(nameof(context));

ArgumentException.ThrowIfNullOrWhiteSpace(connectionStringName);

var conString = context.Configuration.GetConnectionString(connectionStringName);
_ = services
.AddDbContext<TContext>(
options => options.UseSqlite(conString ?? throw new InvalidOperationException($"Connection string '{connectionStringName}' not found.")),
serviceLifetime,
serviceLifetime == ServiceLifetime.Singleton ? ServiceLifetime.Singleton : ServiceLifetime.Scoped)
.AddDefaultIdentity<TUser>()
.AddEntityFrameworkStores<TContext>();
return services;
}

/// <summary>Configures Entity Framework Core with a SQLite provider and caller-provided Identity services.</summary>
/// <remarks>This method registers the DbContext with the SQLite provider and configures ASP.NET Core
/// Identity using the supplied callback. It is typically called during application startup to enable
Expand Down
Loading
Loading