From deed65b9bbb0f1a54a99342571f4607adfef9468 Mon Sep 17 00:00:00 2001 From: Chris Pulman Date: Wed, 30 Aug 2023 22:53:34 +0100 Subject: [PATCH] Add Identity.EntityFrameworkCore --- ...osting.Identity.EntityFrameworkCore.csproj | 31 +++++++++ ...ostBuilderEntityFrameworkCoreExtensions.cs | 69 +++++++++++++++++++ src/CP.Extensions.Hosting.sln | 14 ++-- 3 files changed, 110 insertions(+), 4 deletions(-) create mode 100644 src/CP.Extensions.Hosting.Identity.EntityFrameworkCore/CP.Extensions.Hosting.Identity.EntityFrameworkCore.csproj create mode 100644 src/CP.Extensions.Hosting.Identity.EntityFrameworkCore/HostBuilderEntityFrameworkCoreExtensions.cs diff --git a/src/CP.Extensions.Hosting.Identity.EntityFrameworkCore/CP.Extensions.Hosting.Identity.EntityFrameworkCore.csproj b/src/CP.Extensions.Hosting.Identity.EntityFrameworkCore/CP.Extensions.Hosting.Identity.EntityFrameworkCore.csproj new file mode 100644 index 0000000..fe673a9 --- /dev/null +++ b/src/CP.Extensions.Hosting.Identity.EntityFrameworkCore/CP.Extensions.Hosting.Identity.EntityFrameworkCore.csproj @@ -0,0 +1,31 @@ + + + + net6.0;net7.0 + enable + enable + + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + diff --git a/src/CP.Extensions.Hosting.Identity.EntityFrameworkCore/HostBuilderEntityFrameworkCoreExtensions.cs b/src/CP.Extensions.Hosting.Identity.EntityFrameworkCore/HostBuilderEntityFrameworkCoreExtensions.cs new file mode 100644 index 0000000..e25deb4 --- /dev/null +++ b/src/CP.Extensions.Hosting.Identity.EntityFrameworkCore/HostBuilderEntityFrameworkCoreExtensions.cs @@ -0,0 +1,69 @@ +// 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; + +/// +/// Host Builder Entity Framework Core Extensions. +/// +public static class HostBuilderEntityFrameworkCoreExtensions +{ + /// + /// Uses the entity framework core. + /// + /// The type of the context. + /// The host builder. + /// The connection string Name. + /// An optional action to configure the for the context. This provides an + /// alternative to performing configuration of the context by overriding the + /// method in your derived context. + /// true to perform check verifying that scoped services never gets resolved from root provider; otherwise false. Defaults to false. + /// + /// IHostBuilder. + /// + /// hostBuilder. + public static IHostBuilder UseEntityFrameworkCore(this IHostBuilder hostBuilder, string? connectionStringName, Action configureDatabase, bool validateScopes = false) + where TContext : DbContext + { + if (hostBuilder is null) + { + throw new ArgumentNullException(nameof(hostBuilder)); + } + + return hostBuilder.UseWebHostServices( + (context, services) => + { + var constring = context.Configuration.GetConnectionString(connectionStringName!) ?? throw new InvalidOperationException($"Connection string '{connectionStringName}' not found."); + services.AddDbContext(options => configureDatabase(context, services, options, constring)); + }, + validateScopes); + } + + /// + /// Uses the web host services. + /// + /// The host builder. + /// Adds a delegate for configuring additional services for the host or web application. + /// true to perform check verifying that scoped services never gets resolved from root provider; otherwise false. Defaults to false. + /// IHostBuilder. + /// hostBuilder. + public static IHostBuilder UseWebHostServices(this IHostBuilder hostBuilder, Action 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))); + } +} diff --git a/src/CP.Extensions.Hosting.sln b/src/CP.Extensions.Hosting.sln index 5bb58b0..06b4b15 100644 --- a/src/CP.Extensions.Hosting.sln +++ b/src/CP.Extensions.Hosting.sln @@ -32,13 +32,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CP.Extensions.Hosting.WinFo EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CP.Extensions.Hosting.WinUI", "CP.Extensions.Hosting.WinUI\CP.Extensions.Hosting.WinUI.csproj", "{641302C9-7B83-42E3-8619-4FD1136B03FA}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CP.Extensions.Hosting.ReactiveUI.Wpf", "CP.Extensions.Hosting.ReactiveUI.Wpf\CP.Extensions.Hosting.ReactiveUI.Wpf.csproj", "{FD76D9CB-9323-4555-B471-51CC517EBCBF}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CP.Extensions.Hosting.ReactiveUI.Wpf", "CP.Extensions.Hosting.ReactiveUI.Wpf\CP.Extensions.Hosting.ReactiveUI.Wpf.csproj", "{FD76D9CB-9323-4555-B471-51CC517EBCBF}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CP.Extensions.Hosting.ReactiveUI.WinForms", "CP.Extensions.Hosting.ReactiveUI.WinForms\CP.Extensions.Hosting.ReactiveUI.WinForms.csproj", "{4481115F-6453-4E5A-B9A1-6B252438B391}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CP.Extensions.Hosting.ReactiveUI.WinForms", "CP.Extensions.Hosting.ReactiveUI.WinForms\CP.Extensions.Hosting.ReactiveUI.WinForms.csproj", "{4481115F-6453-4E5A-B9A1-6B252438B391}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CP.Extensions.Hosting.ReactiveUI.WinUI", "CP.Extensions.Hosting.ReactiveUI.WinUI\CP.Extensions.Hosting.ReactiveUI.WinUI.csproj", "{684344D8-09C7-4256-9DD7-5E3E14E68034}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CP.Extensions.Hosting.ReactiveUI.WinUI", "CP.Extensions.Hosting.ReactiveUI.WinUI\CP.Extensions.Hosting.ReactiveUI.WinUI.csproj", "{684344D8-09C7-4256-9DD7-5E3E14E68034}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CP.Extensions.Hosting.PluginService", "CP.Extensions.Hosting.PluginService\CP.Extensions.Hosting.PluginService.csproj", "{C4CC7AF8-E34E-4C5E-8E74-01946A7F97E4}" +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}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -88,6 +90,10 @@ Global {C4CC7AF8-E34E-4C5E-8E74-01946A7F97E4}.Debug|Any CPU.Build.0 = Debug|Any CPU {C4CC7AF8-E34E-4C5E-8E74-01946A7F97E4}.Release|Any CPU.ActiveCfg = Release|Any CPU {C4CC7AF8-E34E-4C5E-8E74-01946A7F97E4}.Release|Any CPU.Build.0 = Release|Any CPU + {36D4DB90-256B-46E2-9BB3-EB0FC2C40175}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {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 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE