You've already forked Extensions.Configuration.EntityFrameworkCore
Working implementation
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Options = RAIC.Extensions.Configuration.EntityFrameworkCore.SqlServer.SqlServerNotificationConfigurationReloaderOptions;
|
||||
|
||||
namespace RAIC.Extensions.Configuration.EntityFrameworkCore.SqlServer.Extensions;
|
||||
|
||||
public static class ServiceCollectionExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds <see cref="SqlServerNotificationConfigurationReloader{,}"/> (a <see cref="Microsoft.Extensions.Hosting.IHostedService"/> implementation)
|
||||
/// and supporting services to the <see cref="IServiceCollection"/>, obtaining its connection string from a <typeparamref name="TDbContext"/> instance.
|
||||
/// </summary>
|
||||
/// <typeparam name="TDbContext">Type of the <see cref="DbContext"/> which implements <see cref="ISettingsDbContext{TSettingDbSet, TSetting}"/></typeparam>
|
||||
/// <typeparam name="TSetting">Concrete type which implements <see cref="ISetting"/></typeparam>
|
||||
/// <param name="services">The service collection to add the services too</param>
|
||||
/// <returns>The service collection it was called on now with added services</returns>
|
||||
/// <remarks>If your connection string contains a password then this method may not work, please use another overload</remarks>
|
||||
/// <exception cref="NullReferenceException">If your <typeparamref name="TDbContext"/> does not have a connection string</exception>
|
||||
public static IServiceCollection AddSqlServerNotificationConfigurationReloadService<TDbContext, TSetting>(this IServiceCollection services)
|
||||
where TDbContext : DbContext, ISettingsDbContext<DbSet<TSetting>, TSetting>
|
||||
where TSetting : class, ISetting
|
||||
{
|
||||
var optionsBuilder = services.AddCoreServices<TDbContext, TSetting>();
|
||||
|
||||
optionsBuilder.Configure<TDbContext>((options, dependency) =>
|
||||
{
|
||||
options.ConnectionString = dependency.Database.GetConnectionString() ?? throw new NullReferenceException($"{typeof(TDbContext).Name} ConnectionString is null");
|
||||
});
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds <see cref="SqlServerNotificationConfigurationReloader{,}"/> (a <see cref="Microsoft.Extensions.Hosting.IHostedService"/> implementation)
|
||||
/// and supporting services to the <see cref="IServiceCollection"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="TDbContext">Type of the <see cref="DbContext"/> which implements <see cref="ISettingsDbContext{,}"/></typeparam>
|
||||
/// <typeparam name="TSetting">Concrete type which implements <see cref="ISetting"/></typeparam>
|
||||
/// <param name="services">The service collection to add the services too</param>
|
||||
/// <param name="configure">
|
||||
/// Action to manually configure the <see cref="Options"/> instance consumed by <see cref="SqlServerNotificationConfigurationReloader{,}"/> eg.
|
||||
/// <code>
|
||||
/// options => {
|
||||
/// options.ConnectionString = context.Configuration.GetConnectionString("Default");
|
||||
/// }
|
||||
/// </code>
|
||||
/// </param>
|
||||
/// <returns>The service collection it was called on now with added services</returns>
|
||||
public static IServiceCollection AddSqlServerNotificationConfigurationReloadService<TDbContext, TSetting>(this IServiceCollection services, Action<Options> configure)
|
||||
where TDbContext : DbContext, ISettingsDbContext<DbSet<TSetting>, TSetting>
|
||||
where TSetting : class, ISetting
|
||||
{
|
||||
var optionsBuilder = services.AddCoreServices<TDbContext, TSetting>();
|
||||
|
||||
optionsBuilder.Configure(configure);
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
|
||||
private static OptionsBuilder<Options> AddCoreServices<TDbContext, TSetting>(this IServiceCollection services)
|
||||
where TDbContext : DbContext, ISettingsDbContext<DbSet<TSetting>, TSetting>
|
||||
where TSetting : class, ISetting
|
||||
{
|
||||
services.AddSingleton(static provider =>
|
||||
{
|
||||
var configRoot = (IConfigurationRoot)provider.GetRequiredService<IConfiguration>(); // DEBT: Is this cast always safe?
|
||||
return configRoot.Providers.OfType<IEntityFrameworkCoreDbSetConfigurationProvider>().Single();
|
||||
});
|
||||
|
||||
return services.AddHostedService<SqlServerNotificationConfigurationReloader<TDbContext, TSetting>>()
|
||||
.AddOptions<Options>().ValidateDataAnnotations().ValidateOnStart();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user