Skip to content

Commit

Permalink
Add Sqlite and SqlServer
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisPulman committed Aug 31, 2023
1 parent b131bea commit 4231076
Show file tree
Hide file tree
Showing 5 changed files with 242 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<ItemGroup Condition=" $(TargetFramework.StartsWith('net6')) ">
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="6.0.21" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.21" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.21" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.21">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand All @@ -23,6 +24,7 @@
<ItemGroup Condition=" $(TargetFramework.StartsWith('net7')) ">
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="7.0.10" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="7.0.10" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.10" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.10">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
// Copyright (c) Chris Pulman. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace CP.Extensions.Hosting.Identity.EntityFrameworkCore;

/// <summary>
/// Host Builder Entity Framework Core Extensions.
/// </summary>
public static class HostBuilderEntityFrameworkCoreExtensions
{
/// <summary>
/// Uses the entity framework core with Sqlite.
/// </summary>
/// <typeparam name="TContext">The type of the context.</typeparam>
/// <typeparam name="TUser">The type of the user.</typeparam>
/// <typeparam name="TRole">The type of the role.</typeparam>
/// <param name="services">The services.</param>
/// <param name="context">The context.</param>
/// <param name="connectionStringName">Name of the connection string.</param>
/// <returns>
/// IServiceCollection.
/// </returns>
/// <exception cref="ArgumentNullException">services
/// or
/// context.</exception>
public static IServiceCollection UseEntityFrameworkCoreSqlite<TContext, TUser, TRole>(this IServiceCollection services, WebHostBuilderContext context, string connectionStringName)
where TContext : DbContext
where TUser : class
where TRole : class
{
if (services == null)
{
throw new ArgumentNullException(nameof(services));
}

if (context == null)
{
throw new ArgumentNullException(nameof(context));
}

if (string.IsNullOrWhiteSpace(connectionStringName))
{
throw new ArgumentException("Value cannot be null or whitespace.", nameof(connectionStringName));
}

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

/// <summary>
/// Uses the entity framework core with Sqlite.
/// </summary>
/// <typeparam name="TContext">The type of the context.</typeparam>
/// <typeparam name="TUser">The type of the user.</typeparam>
/// <param name="services">The services.</param>
/// <param name="context">The context.</param>
/// <param name="connectionStringName">Name of the connection string.</param>
/// <returns>
/// IServiceCollection.
/// </returns>
/// <exception cref="ArgumentNullException">services
/// or
/// context.</exception>
public static IServiceCollection UseEntityFrameworkCoreSqlite<TContext, TUser>(this IServiceCollection services, WebHostBuilderContext context, string connectionStringName)
where TContext : DbContext
where TUser : class
{
if (services == null)
{
throw new ArgumentNullException(nameof(services));
}

if (context == null)
{
throw new ArgumentNullException(nameof(context));
}

if (string.IsNullOrWhiteSpace(connectionStringName))
{
throw new ArgumentException("Value cannot be null or whitespace.", nameof(connectionStringName));
}

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

/// <summary>
/// Uses the web host services.
/// </summary>
/// <param name="hostBuilder">The host builder.</param>
/// <param name="configureServices">Adds a delegate for configuring additional services for the host or web application.</param>
/// <param name="validateScopes"><c>true</c> to perform check verifying that scoped services never gets resolved from root provider; otherwise <c>false</c>. Defaults to <c>false</c>.</param>
/// <returns>IHostBuilder.</returns>
/// <exception cref="System.ArgumentNullException">hostBuilder.</exception>
public static IHostBuilder UseWebHostServices(this IHostBuilder hostBuilder, Action<WebHostBuilderContext, IServiceCollection> configureServices, bool validateScopes = false)
{
if (hostBuilder is null)
{
throw new ArgumentNullException(nameof(hostBuilder));
}

return hostBuilder.ConfigureWebHostDefaults(webBuilder =>
webBuilder.UseDefaultServiceProvider(options => options.ValidateScopes = validateScopes)
.Configure(app => app.Run(async (_) => await Task.CompletedTask)) // Dummy app.Run to prevent 'No application service provider was found' error.
.ConfigureServices((context, services) => configureServices(context, services)));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" />
</ItemGroup>

<ItemGroup Condition=" $(TargetFramework.StartsWith('net6')) ">
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="6.0.21" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.21" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.21" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.21">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

<ItemGroup Condition=" $(TargetFramework.StartsWith('net7')) ">
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="7.0.10" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="7.0.10" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.10" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.10">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -16,34 +16,90 @@ namespace CP.Extensions.Hosting.Identity.EntityFrameworkCore;
public static class HostBuilderEntityFrameworkCoreExtensions
{
/// <summary>
/// Uses the entity framework core.
/// Uses the entity framework core with SqlServer.
/// </summary>
/// <typeparam name="TContext">The type of the context.</typeparam>
/// <param name="hostBuilder">The host builder.</param>
/// <param name="connectionStringName">The connection string Name.</param>
/// <param name="configureDatabase">An optional action to configure the <see cref="DbContextOptions" /> for the context. This provides an
/// alternative to performing configuration of the context by overriding the
/// <see cref="DbContext.OnConfiguring" /> method in your derived context.</param>
/// <param name="validateScopes"><c>true</c> to perform check verifying that scoped services never gets resolved from root provider; otherwise <c>false</c>. Defaults to <c>false</c>.</param>
/// <typeparam name="TUser">The type of the user.</typeparam>
/// <typeparam name="TRole">The type of the role.</typeparam>
/// <param name="services">The services.</param>
/// <param name="context">The context.</param>
/// <param name="connectionStringName">Name of the connection string.</param>
/// <returns>
/// IHostBuilder.
/// IServiceCollection.
/// </returns>
/// <exception cref="System.ArgumentNullException">hostBuilder.</exception>
public static IHostBuilder UseEntityFrameworkCore<TContext>(this IHostBuilder hostBuilder, string? connectionStringName, Action<WebHostBuilderContext, IServiceCollection, DbContextOptionsBuilder, string> configureDatabase, bool validateScopes = false)
/// <exception cref="ArgumentNullException">services
/// or
/// context.</exception>
public static IServiceCollection UseEntityFrameworkCoreSqlServer<TContext, TUser, TRole>(this IServiceCollection services, WebHostBuilderContext context, string connectionStringName)
where TContext : DbContext
where TUser : class
where TRole : class
{
if (hostBuilder is null)
if (services == null)
{
throw new ArgumentNullException(nameof(hostBuilder));
throw new ArgumentNullException(nameof(services));
}

if (context == null)
{
throw new ArgumentNullException(nameof(context));
}

if (string.IsNullOrWhiteSpace(connectionStringName))
{
throw new ArgumentException("Value cannot be null or whitespace.", nameof(connectionStringName));
}

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

/// <summary>
/// Uses the entity framework core with SqlServer.
/// </summary>
/// <typeparam name="TContext">The type of the context.</typeparam>
/// <typeparam name="TUser">The type of the user.</typeparam>
/// <param name="services">The services.</param>
/// <param name="context">The context.</param>
/// <param name="connectionStringName">Name of the connection string.</param>
/// <returns>
/// IServiceCollection.
/// </returns>
/// <exception cref="ArgumentNullException">services
/// or
/// context.</exception>
public static IServiceCollection UseEntityFrameworkCoreSqlServer<TContext, TUser>(this IServiceCollection services, WebHostBuilderContext context, string connectionStringName)
where TContext : DbContext
where TUser : class
{
if (services == null)
{
throw new ArgumentNullException(nameof(services));
}

if (context == null)
{
throw new ArgumentNullException(nameof(context));
}

if (string.IsNullOrWhiteSpace(connectionStringName))
{
throw new ArgumentException("Value cannot be null or whitespace.", nameof(connectionStringName));
}

return hostBuilder.UseWebHostServices(
(context, services) =>
{
var constring = context.Configuration.GetConnectionString(connectionStringName!) ?? throw new InvalidOperationException($"Connection string '{connectionStringName}' not found.");
services.AddDbContext<TContext>(options => configureDatabase(context, services, options, constring));
},
validateScopes);
var conString = context.Configuration.GetConnectionString(connectionStringName);
services.AddDbContext<TContext>(options =>
options.UseSqlServer(conString ??
throw new InvalidOperationException($"Connection string '{connectionStringName}' not found.")))
.AddDefaultIdentity<TUser>()
.AddEntityFrameworkStores<TContext>();
return services;
}

/// <summary>
Expand Down
8 changes: 7 additions & 1 deletion src/CP.Extensions.Hosting.sln
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CP.Extensions.Hosting.React
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CP.Extensions.Hosting.PluginService", "CP.Extensions.Hosting.PluginService\CP.Extensions.Hosting.PluginService.csproj", "{C4CC7AF8-E34E-4C5E-8E74-01946A7F97E4}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CP.Extensions.Hosting.Identity.EntityFrameworkCore", "CP.Extensions.Hosting.Identity.EntityFrameworkCore\CP.Extensions.Hosting.Identity.EntityFrameworkCore.csproj", "{36D4DB90-256B-46E2-9BB3-EB0FC2C40175}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CP.Extensions.Hosting.Identity.EntityFrameworkCore.SqlServer", "CP.Extensions.Hosting.Identity.EntityFrameworkCore\CP.Extensions.Hosting.Identity.EntityFrameworkCore.SqlServer.csproj", "{36D4DB90-256B-46E2-9BB3-EB0FC2C40175}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CP.Extensions.Hosting.Identity.EntityFrameworkCore.Sqlite", "CP.Extensions.Hosting.Identity.EntityFrameworkCore.Sqlite\CP.Extensions.Hosting.Identity.EntityFrameworkCore.Sqlite.csproj", "{9D98227B-C97B-429C-AEAF-88A9514A2B0E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -94,6 +96,10 @@ Global
{36D4DB90-256B-46E2-9BB3-EB0FC2C40175}.Debug|Any CPU.Build.0 = Debug|Any CPU
{36D4DB90-256B-46E2-9BB3-EB0FC2C40175}.Release|Any CPU.ActiveCfg = Release|Any CPU
{36D4DB90-256B-46E2-9BB3-EB0FC2C40175}.Release|Any CPU.Build.0 = Release|Any CPU
{9D98227B-C97B-429C-AEAF-88A9514A2B0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9D98227B-C97B-429C-AEAF-88A9514A2B0E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9D98227B-C97B-429C-AEAF-88A9514A2B0E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9D98227B-C97B-429C-AEAF-88A9514A2B0E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down

0 comments on commit 4231076

Please sign in to comment.