From b549903e7f04bea5619dbfb53f028dc313292dc4 Mon Sep 17 00:00:00 2001 From: VahidN Date: Fri, 5 Apr 2024 19:49:34 +0330 Subject: [PATCH] Change `DisableLogging` to `ConfigureLogging` and don't use negative names --- README.md | 34 +-- .../EFCoreSecondLevelCacheOptions.cs | 12 +- .../EFCoreSecondLevelCacheSettings.cs | 4 +- .../EFDebugLogger.cs | 4 +- .../Startup.cs | 144 ++++++------- .../EFServiceProvider.cs | 114 +++++----- .../EFServiceProvider.cs | 103 ++++----- .../Issues/Issue125EF5x/EFServiceProvider.cs | 83 ++++---- .../Issue12PostgreSql/EFServiceProvider.cs | 101 +++++---- .../Issues/Issue154/EFServiceProvider.cs | 136 ++++++------ .../Issues/Issue192/EFServiceProvider.cs | 40 ++-- .../Issue9SQLiteInt32/EFServiceProvider.cs | 197 +++++++++--------- 12 files changed, 492 insertions(+), 480 deletions(-) diff --git a/README.md b/README.md index 13302b4..ecfd7c1 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ namespace EFCoreSecondLevelCacheInterceptor.AspNetCoreSample public void ConfigureServices(IServiceCollection services) { services.AddEFSecondLevelCache(options => - options.UseMemoryCacheProvider().DisableLogging(true).UseCacheKeyPrefix("EF_") + options.UseMemoryCacheProvider().ConfigureLogging(true).UseCacheKeyPrefix("EF_") // Fallback on db if the caching provider fails. .UseDbCallsIfCachingProviderIsDown(TimeSpan.FromMinutes(1)) @@ -92,7 +92,7 @@ namespace EFSecondLevelCache.Core.AspNetCoreSample { const string providerName1 = "InMemory1"; services.AddEFSecondLevelCache(options => - options.UseEasyCachingCoreProvider(providerName1, isHybridCache: false).DisableLogging(true).UseCacheKeyPrefix("EF_") + options.UseEasyCachingCoreProvider(providerName1, isHybridCache: false).ConfigureLogging(true).UseCacheKeyPrefix("EF_") // Fallback on db if the caching provider fails. .UseDbCallsIfCachingProviderIsDown(TimeSpan.FromMinutes(1)) ); @@ -151,7 +151,7 @@ namespace EFSecondLevelCache.Core.AspNetCoreSample { const string providerName1 = "Redis1"; services.AddEFSecondLevelCache(options => - options.UseEasyCachingCoreProvider(providerName1, isHybridCache: false).DisableLogging(true).UseCacheKeyPrefix("EF_") + options.UseEasyCachingCoreProvider(providerName1, isHybridCache: false).ConfigureLogging(true).UseCacheKeyPrefix("EF_") // Fallback on db if the caching provider fails (for example, if Redis is down). .UseDbCallsIfCachingProviderIsDown(TimeSpan.FromMinutes(1)) ); @@ -205,7 +205,7 @@ services.AddEFSecondLevelCache(options => isHybridCache: false) // `Or` you can set the cache key prefix per tenant dynamically .UseCacheKeyPrefix(serviceProvider => "EF_" + serviceProvider.GetRequiredService().HttpContext.Request.Headers["tenant-id"]) - .DisableLogging(true) + .ConfigureLogging(true) .UseCacheKeyPrefix("EF_") // Fallback on db if the caching provider fails. .UseDbCallsIfCachingProviderIsDown(TimeSpan.FromMinutes(1)) @@ -236,7 +236,7 @@ namespace EFSecondLevelCache.Core.AspNetCoreSample public void ConfigureServices(IServiceCollection services) { services.AddEFSecondLevelCache(options => - options.UseCacheManagerCoreProvider().DisableLogging(true).UseCacheKeyPrefix("EF_") + options.UseCacheManagerCoreProvider().ConfigureLogging(true).UseCacheKeyPrefix("EF_") // Fallback on db if the caching provider fails. .UseDbCallsIfCachingProviderIsDown(TimeSpan.FromMinutes(1)) ); @@ -288,7 +288,7 @@ services.AddSingleton(typeof(ICacheManagerConfiguration), services.AddSingleton(typeof(ICacheManager<>), typeof(BaseCacheManager<>)); services.AddEFSecondLevelCache(options => - options.UseCacheManagerCoreProvider().DisableLogging(true).UseCacheKeyPrefix("EF_") + options.UseCacheManagerCoreProvider().ConfigureLogging(true).UseCacheKeyPrefix("EF_") // Fallback on db if the caching provider fails. .UseDbCallsIfCachingProviderIsDown(TimeSpan.FromMinutes(1)) ); @@ -365,7 +365,7 @@ NOTE: It doesn't matter where the `Cacheable` method is located in this expressi Also it's possible to set the `Cacheable()` method's settings globally: ```csharp -services.AddEFSecondLevelCache(options => options.UseMemoryCacheProvider(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(5)).DisableLogging(true) +services.AddEFSecondLevelCache(options => options.UseMemoryCacheProvider(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(5)).ConfigureLogging(true) .UseCacheKeyPrefix("EF_") // Fallback on db if the caching provider fails. .UseDbCallsIfCachingProviderIsDown(TimeSpan.FromMinutes(1)) @@ -397,7 +397,7 @@ namespace EFCoreSecondLevelCacheInterceptor.AspNetCoreSample { services.AddEFSecondLevelCache(options => { - options.UseMemoryCacheProvider().DisableLogging(true).UseCacheKeyPrefix("EF_"); + options.UseMemoryCacheProvider().ConfigureLogging(true).UseCacheKeyPrefix("EF_"); options.CacheAllQueries(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(30)); // Fallback on db if the caching provider fails. options.UseDbCallsIfCachingProviderIsDown(TimeSpan.FromMinutes(1)); @@ -421,7 +421,7 @@ namespace EFCoreSecondLevelCacheInterceptor.AspNetCoreSample { services.AddEFSecondLevelCache(options => { - options.UseMemoryCacheProvider().DisableLogging(true).UseCacheKeyPrefix("EF_") + options.UseMemoryCacheProvider().ConfigureLogging(true).UseCacheKeyPrefix("EF_") // Fallback on db if the caching provider fails. .UseDbCallsIfCachingProviderIsDown(TimeSpan.FromMinutes(1)) /*.CacheQueriesContainingTypes( @@ -452,7 +452,7 @@ namespace EFCoreSecondLevelCacheInterceptor.AspNetCoreSample { services.AddEFSecondLevelCache(options => { - options.UseMemoryCacheProvider().DisableLogging(true).UseCacheKeyPrefix("EF_") + options.UseMemoryCacheProvider().ConfigureLogging(true).UseCacheKeyPrefix("EF_") // Fallback on db if the caching provider fails. .UseDbCallsIfCachingProviderIsDown(TimeSpan.FromMinutes(1)) // How to skip caching specific commands @@ -475,7 +475,7 @@ namespace EFCoreSecondLevelCacheInterceptor.AspNetCoreSample { services.AddEFSecondLevelCache(options => { - options.UseMemoryCacheProvider().DisableLogging(true).UseCacheKeyPrefix("EF_") + options.UseMemoryCacheProvider().ConfigureLogging(true).UseCacheKeyPrefix("EF_") // Fallback on db if the caching provider fails. .UseDbCallsIfCachingProviderIsDown(TimeSpan.FromMinutes(1)) // Don't cache null values. Remove this optional setting if it's not necessary. @@ -498,7 +498,7 @@ namespace EFCoreSecondLevelCacheInterceptor.AspNetCoreSample { services.AddEFSecondLevelCache(options => { - options.UseMemoryCacheProvider().DisableLogging(true).UseCacheKeyPrefix("EF_") + options.UseMemoryCacheProvider().ConfigureLogging(true).UseCacheKeyPrefix("EF_") // Fallback on db if the caching provider fails. .UseDbCallsIfCachingProviderIsDown(TimeSpan.FromMinutes(1)) /*.CacheAllQueriesExceptContainingTypes( @@ -529,7 +529,7 @@ namespace EFCoreSecondLevelCacheInterceptor.AspNetCoreSample { services.AddEFSecondLevelCache(options => { - options.UseMemoryCacheProvider().DisableLogging(true).UseCacheKeyPrefix("EF_") + options.UseMemoryCacheProvider().ConfigureLogging(true).UseCacheKeyPrefix("EF_") // Fallback on db if the caching provider fails. .UseDbCallsIfCachingProviderIsDown(TimeSpan.FromMinutes(1)) .SkipCacheInvalidationCommands(commandText => @@ -563,11 +563,11 @@ namespace EFCoreSecondLevelCacheInterceptor.AspNetCoreSample ## Does it work?! You should enable the logging system to see the behind the scene of the caching interceptor. -First set the `DisableLogging(false)`: +First set the `ConfigureLogging(true)`: ```c# services.AddEFSecondLevelCache(options => - options.UseMemoryCacheProvider().DisableLogging(false).UseCacheKeyPrefix("EF_") + options.UseMemoryCacheProvider().ConfigureLogging(true).UseCacheKeyPrefix("EF_") // Fallback on db if the caching provider fails. .UseDbCallsIfCachingProviderIsDown(TimeSpan.FromMinutes(1)) ``` @@ -587,11 +587,11 @@ And then change the log level to `Debug` in your `appsettings.json` file: } ``` -Or ... you can use the second optional parameter of the `DisableLogging` method to access the published events of this library more easily: +Or ... you can use the second optional parameter of the `ConfigureLogging` method to access the published events of this library more easily: ```c# - .DisableLogging(disable: !environment.IsDevelopment(), cacheableEvent: args => + .ConfigureLogging(enable: environment.IsDevelopment(), cacheableEvent: args => { switch (args.EventId) { diff --git a/src/EFCoreSecondLevelCacheInterceptor/EFCoreSecondLevelCacheOptions.cs b/src/EFCoreSecondLevelCacheInterceptor/EFCoreSecondLevelCacheOptions.cs index fed75a4..57071c1 100644 --- a/src/EFCoreSecondLevelCacheInterceptor/EFCoreSecondLevelCacheOptions.cs +++ b/src/EFCoreSecondLevelCacheInterceptor/EFCoreSecondLevelCacheOptions.cs @@ -318,19 +318,19 @@ public EFCoreSecondLevelCacheOptions UseCacheKeyPrefix(string prefix) } /// - /// Should the debug level logging be disabled? - /// Set it to true for maximum performance. + /// Should the debug level logging be enabled? + /// Set it to false for maximum performance. /// - /// Set it to false, to enable logging + /// Set it to true, to enable logging /// - /// If you set DisableLogging to false, this delegate will give you the internal caching + /// If you set EnableLogging to true, this delegate will give you the internal caching /// events of the library. /// /// - public EFCoreSecondLevelCacheOptions DisableLogging(bool disable = false, + public EFCoreSecondLevelCacheOptions ConfigureLogging(bool enable = false, Action<(CacheableLogEventId EventId, string Message)>? cacheableEvent = null) { - Settings.DisableLogging = disable; + Settings.EnableLogging = enable; Settings.CacheableEvent = cacheableEvent; return this; diff --git a/src/EFCoreSecondLevelCacheInterceptor/EFCoreSecondLevelCacheSettings.cs b/src/EFCoreSecondLevelCacheInterceptor/EFCoreSecondLevelCacheSettings.cs index 1d83f57..6081d79 100644 --- a/src/EFCoreSecondLevelCacheInterceptor/EFCoreSecondLevelCacheSettings.cs +++ b/src/EFCoreSecondLevelCacheInterceptor/EFCoreSecondLevelCacheSettings.cs @@ -67,9 +67,9 @@ public class EFCoreSecondLevelCacheSettings public SkipCacheSpecificQueriesOptions SkipCacheSpecificQueriesOptions { get; set; } = new(null); /// - /// Should the debug level logging be disabled? + /// Should the debug level logging be enabled? /// - public bool DisableLogging { set; get; } + public bool EnableLogging { set; get; } /// /// Fallback on db if the caching provider (redis) is down. diff --git a/src/EFCoreSecondLevelCacheInterceptor/EFDebugLogger.cs b/src/EFCoreSecondLevelCacheInterceptor/EFDebugLogger.cs index 5b65dd6..8cd27a3 100644 --- a/src/EFCoreSecondLevelCacheInterceptor/EFDebugLogger.cs +++ b/src/EFCoreSecondLevelCacheInterceptor/EFDebugLogger.cs @@ -26,9 +26,9 @@ public EFDebugLogger(IOptions cacheSettings, ILo throw new ArgumentNullException(nameof(logger)); } - var disableLogging = cacheSettings.Value.DisableLogging; + var enableLogging = cacheSettings.Value.EnableLogging; _cacheableEvent = cacheSettings.Value.CacheableEvent; - IsLoggerEnabled = !disableLogging && (_cacheableEvent is not null || logger.IsEnabled(LogLevel.Debug)); + IsLoggerEnabled = enableLogging && (_cacheableEvent is not null || logger.IsEnabled(LogLevel.Debug)); if (IsLoggerEnabled) { diff --git a/src/Tests/EFCoreSecondLevelCacheInterceptor.AspNetCoreSample/Startup.cs b/src/Tests/EFCoreSecondLevelCacheInterceptor.AspNetCoreSample/Startup.cs index 45afe78..bb116ec 100644 --- a/src/Tests/EFCoreSecondLevelCacheInterceptor.AspNetCoreSample/Startup.cs +++ b/src/Tests/EFCoreSecondLevelCacheInterceptor.AspNetCoreSample/Startup.cs @@ -1,92 +1,92 @@ +using System; +using EFCoreSecondLevelCacheInterceptor.Tests.DataLayer; using EFCoreSecondLevelCacheInterceptor.Tests.DataLayer.Utils; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -using EFCoreSecondLevelCacheInterceptor.Tests.DataLayer; -using EFCoreSecondLevelCacheInterceptor.Tests.DataLayer.Entities; -using System; -namespace EFCoreSecondLevelCacheInterceptor.AspNetCoreSample +namespace EFCoreSecondLevelCacheInterceptor.AspNetCoreSample; + +public class Startup { - public class Startup + private readonly string _contentRootPath; + private readonly IWebHostEnvironment _env; + + public Startup(IConfiguration configuration, IWebHostEnvironment env) { - private readonly string _contentRootPath; + _env = env; + _contentRootPath = env.ContentRootPath; + Configuration = configuration; + } - public Startup(IConfiguration configuration, IWebHostEnvironment env) + public IConfiguration Configuration { get; } + + public void ConfigureServices(IServiceCollection services) + { + services.AddEFSecondLevelCache(options => { - _contentRootPath = env.ContentRootPath; - Configuration = configuration; - } + options.UseMemoryCacheProvider(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(30)) + .ConfigureLogging(_env.IsDevelopment()) + + //.CacheAllQueries(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(30) + /*.CacheQueriesContainingTypes( + CacheExpirationMode.Absolute, TimeSpan.FromMinutes(30), + typeof(Post), typeof(Product), typeof(User) + )*/ + .CacheQueriesContainingTableNames(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(30), + TableNameComparison.ContainsOnly, "posts", "products", "users").SkipCachingCommands(commandText => + + // How to skip caching specific commands + commandText.Contains("NEWID()", StringComparison.InvariantCultureIgnoreCase)) + + // Don't cache null values. Remove this optional setting if it's not necessary. + .SkipCachingResults(result + => result.Value == null || (result.Value is EFTableRows rows && rows.RowsCount == 0)) + .SkipCacheInvalidationCommands(commandText => - public IConfiguration Configuration { get; } + // How to skip invalidating the related cache entries of this query + commandText.Contains("NEWID()", StringComparison.InvariantCultureIgnoreCase)); + }); - public void ConfigureServices(IServiceCollection services) + var connectionString = Configuration["ConnectionStrings:ApplicationDbContextConnection"]; + + if (connectionString.Contains("%CONTENTROOTPATH%")) { - services.AddEFSecondLevelCache(options => - { - options.UseMemoryCacheProvider(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(30)) - .DisableLogging(false) - //.CacheAllQueries(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(30) - /*.CacheQueriesContainingTypes( - CacheExpirationMode.Absolute, TimeSpan.FromMinutes(30), - typeof(Post), typeof(Product), typeof(User) - )*/ - .CacheQueriesContainingTableNames( - CacheExpirationMode.Absolute, TimeSpan.FromMinutes(30), - TableNameComparison.ContainsOnly, - "posts", "products", "users" - ) - .SkipCachingCommands(commandText => - // How to skip caching specific commands - commandText.Contains("NEWID()", StringComparison.InvariantCultureIgnoreCase)) - // Don't cache null values. Remove this optional setting if it's not necessary. - .SkipCachingResults(result => - result.Value == null || (result.Value is EFTableRows rows && rows.RowsCount == 0)) - .SkipCacheInvalidationCommands(commandText => - // How to skip invalidating the related cache entries of this query - commandText.Contains("NEWID()", StringComparison.InvariantCultureIgnoreCase)); - }); - - var connectionString = Configuration["ConnectionStrings:ApplicationDbContextConnection"]; - if (connectionString.Contains("%CONTENTROOTPATH%")) - { - connectionString = connectionString.Replace("%CONTENTROOTPATH%", _contentRootPath); - } - services.AddConfiguredMsSqlDbContext(connectionString); - - services.AddControllersWithViews(); + connectionString = connectionString.Replace("%CONTENTROOTPATH%", _contentRootPath); } - public void Configure(IApplicationBuilder app, IWebHostEnvironment env, - IServiceScopeFactory scopeFactory) + services.AddConfiguredMsSqlDbContext(connectionString); + + services.AddControllersWithViews(); + } + + public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceScopeFactory scopeFactory) + { + scopeFactory.Initialize(); + scopeFactory.SeedData(); + + if (env.IsDevelopment()) { - scopeFactory.Initialize(); - scopeFactory.SeedData(); - - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - } - else - { - app.UseExceptionHandler("/Home/Error"); - app.UseHsts(); - } - app.UseHttpsRedirection(); - app.UseStaticFiles(); - - app.UseRouting(); - - app.UseAuthorization(); - - app.UseEndpoints(endpoints => - { - endpoints.MapControllerRoute( - name: "default", - pattern: "{controller=Home}/{action=Index}/{id?}"); - }); + app.UseDeveloperExceptionPage(); } + else + { + app.UseExceptionHandler("/Home/Error"); + app.UseHsts(); + } + + app.UseHttpsRedirection(); + app.UseStaticFiles(); + + app.UseRouting(); + + app.UseAuthorization(); + + app.UseEndpoints(endpoints => + { + endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}"); + }); } } \ No newline at end of file diff --git a/src/Tests/EFCoreSecondLevelCacheInterceptor.PerformanceTests/EFServiceProvider.cs b/src/Tests/EFCoreSecondLevelCacheInterceptor.PerformanceTests/EFServiceProvider.cs index a91f7bc..116d62f 100644 --- a/src/Tests/EFCoreSecondLevelCacheInterceptor.PerformanceTests/EFServiceProvider.cs +++ b/src/Tests/EFCoreSecondLevelCacheInterceptor.PerformanceTests/EFServiceProvider.cs @@ -1,74 +1,78 @@ using System; -using Microsoft.Extensions.DependencyInjection; -using System.Threading; using System.IO; +using System.Threading; +using System.Threading.Tasks; using EFCoreSecondLevelCacheInterceptor.Tests.DataLayer; using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -using System.Threading.Tasks; -namespace EFCoreSecondLevelCacheInterceptor.PerformanceTests +namespace EFCoreSecondLevelCacheInterceptor.PerformanceTests; + +public static class EFServiceProvider { - public static class EFServiceProvider + private static readonly Lazy _serviceProviderBuilder = + new(getServiceProvider, LazyThreadSafetyMode.ExecutionAndPublication); + + /// + /// A lazy loaded thread-safe singleton + /// + public static IServiceProvider Instance { get; } = _serviceProviderBuilder.Value; + + public static T GetRequiredService() + => Instance.GetRequiredService(); + + public static void RunInContext(Action action) { - private static readonly Lazy _serviceProviderBuilder = - new Lazy(getServiceProvider, LazyThreadSafetyMode.ExecutionAndPublication); + using var serviceScope = GetRequiredService().CreateScope(); + using var context = serviceScope.ServiceProvider.GetRequiredService(); + action(context); + } - /// - /// A lazy loaded thread-safe singleton - /// - public static IServiceProvider Instance { get; } = _serviceProviderBuilder.Value; + public static async Task RunInContextAsync(Func action) + { + using var serviceScope = GetRequiredService().CreateScope(); + using var context = serviceScope.ServiceProvider.GetRequiredService(); + await action(context); + } - public static T GetRequiredService() - { - return Instance.GetRequiredService(); - } + private static IServiceProvider getServiceProvider() + { + var services = new ServiceCollection(); + services.AddOptions(); - public static void RunInContext(Action action) - { - using var serviceScope = GetRequiredService().CreateScope(); - using var context = serviceScope.ServiceProvider.GetRequiredService(); - action(context); - } + services.AddLogging(cfg => cfg.AddConsole().AddDebug().SetMinimumLevel(LogLevel.Warning)); + services.AddEFSecondLevelCache(options => options.UseMemoryCacheProvider().ConfigureLogging(true)); - public static async Task RunInContextAsync(Func action) - { - using var serviceScope = GetRequiredService().CreateScope(); - using var context = serviceScope.ServiceProvider.GetRequiredService(); - await action(context); - } + var basePath = Directory.GetCurrentDirectory(); + Console.WriteLine($"Using `{basePath}` as the ContentRootPath"); + + var configuration = new ConfigurationBuilder().SetBasePath(basePath) + .AddJsonFile("appsettings.json", false, true).Build(); + + services.AddSingleton(_ => configuration); + services.AddConfiguredMsSqlDbContext(getConnectionString(basePath, configuration)); - private static IServiceProvider getServiceProvider() + return services.BuildServiceProvider(); + } + + private static string getConnectionString(string basePath, IConfigurationRoot configuration) + { + var testsFolder = basePath.Split(new[] { - var services = new ServiceCollection(); - services.AddOptions(); - - services.AddLogging(cfg => cfg.AddConsole().AddDebug().SetMinimumLevel(LogLevel.Warning)); - services.AddEFSecondLevelCache(options => options.UseMemoryCacheProvider().DisableLogging(true)); - - var basePath = Directory.GetCurrentDirectory(); - Console.WriteLine($"Using `{basePath}` as the ContentRootPath"); - var configuration = new ConfigurationBuilder() - .SetBasePath(basePath) - .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) - .Build(); - services.AddSingleton(_ => configuration); - services.AddConfiguredMsSqlDbContext(getConnectionString(basePath, configuration)); - - return services.BuildServiceProvider(); - } + "\\Tests\\" + }, StringSplitOptions.RemoveEmptyEntries)[0]; - private static string getConnectionString(string basePath, IConfigurationRoot configuration) + var contentRootPath = Path.Combine(testsFolder, "Tests", "EFCoreSecondLevelCacheInterceptor.AspNetCoreSample"); + var connectionString = configuration["ConnectionStrings:ApplicationDbContextConnection"]; + + if (connectionString.Contains("%CONTENTROOTPATH%")) { - var testsFolder = basePath.Split(new[] { "\\Tests\\" }, StringSplitOptions.RemoveEmptyEntries)[0]; - var contentRootPath = Path.Combine(testsFolder, "Tests", "EFCoreSecondLevelCacheInterceptor.AspNetCoreSample"); - var connectionString = configuration["ConnectionStrings:ApplicationDbContextConnection"]; - if (connectionString.Contains("%CONTENTROOTPATH%")) - { - connectionString = connectionString.Replace("%CONTENTROOTPATH%", contentRootPath); - } - Console.WriteLine($"Using {connectionString}"); - return connectionString; + connectionString = connectionString.Replace("%CONTENTROOTPATH%", contentRootPath); } + + Console.WriteLine($"Using {connectionString}"); + + return connectionString; } } \ No newline at end of file diff --git a/src/Tests/Issues/Issue123WithMessagePack/EFServiceProvider.cs b/src/Tests/Issues/Issue123WithMessagePack/EFServiceProvider.cs index 4332513..3d8a0a2 100644 --- a/src/Tests/Issues/Issue123WithMessagePack/EFServiceProvider.cs +++ b/src/Tests/Issues/Issue123WithMessagePack/EFServiceProvider.cs @@ -25,7 +25,8 @@ public static class EFServiceProvider /// public static IServiceProvider Instance { get; } = _serviceProviderBuilder.Value; - public static T GetRequiredService() => Instance.GetRequiredService(); + public static T GetRequiredService() + => Instance.GetRequiredService(); public static void RunInContext(Action action) { @@ -49,73 +50,74 @@ private static IServiceProvider getServiceProvider() services.AddLogging(cfg => cfg.AddConsole().AddDebug().SetMinimumLevel(LogLevel.Debug)); const string providerName = "Redis1"; + services.AddEasyCaching(o => - { - o.UseRedis(cfg => - { - cfg.SerializerName = "Pack"; - cfg.DBConfig.Endpoints.Add(new ServerEndPoint("127.0.0.1", 6379)); - cfg.DBConfig.AllowAdmin = true; - cfg.DBConfig.ConnectionTimeout = 10000; - }, providerName); - o.WithMessagePack(so => - { - so.EnableCustomResolver = true; - so.CustomResolvers = CompositeResolver.Create( - new IMessagePackFormatter[] - { - DBNullFormatter - .Instance, // This is necessary for the null values - }, - new IFormatterResolver[] - { - NativeDateTimeResolver.Instance, - ContractlessStandardResolver.Instance, - StandardResolverAllowPrivate.Instance, - TypelessContractlessStandardResolver.Instance, - DynamicGenericResolver.Instance, - }); - }, - "Pack"); - }); + { + o.UseRedis(cfg => + { + cfg.SerializerName = "Pack"; + cfg.DBConfig.Endpoints.Add(new ServerEndPoint("127.0.0.1", 6379)); + cfg.DBConfig.AllowAdmin = true; + cfg.DBConfig.ConnectionTimeout = 10000; + }, providerName); + + o.WithMessagePack(so => + { + so.EnableCustomResolver = true; + + so.CustomResolvers = CompositeResolver.Create(new IMessagePackFormatter[] + { + DBNullFormatter.Instance // This is necessary for the null values + }, new IFormatterResolver[] + { + NativeDateTimeResolver.Instance, ContractlessStandardResolver.Instance, + StandardResolverAllowPrivate.Instance, TypelessContractlessStandardResolver.Instance, + DynamicGenericResolver.Instance + }); + }, "Pack"); + }); + services.AddEFSecondLevelCache(o => - { - o.UseEasyCachingCoreProvider(providerName).DisableLogging(); - o.CacheAllQueries(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(10)); - o.UseCacheKeyPrefix("EF_"); - }); + { + o.UseEasyCachingCoreProvider(providerName).ConfigureLogging(true); + o.CacheAllQueries(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(10)); + o.UseCacheKeyPrefix("EF_"); + }); var basePath = Directory.GetCurrentDirectory(); Console.WriteLine($"Using `{basePath}` as the ContentRootPath"); - var configuration = new ConfigurationBuilder() - .SetBasePath(basePath) - .AddJsonFile("appsettings.json", false, true) - .Build(); + + var configuration = new ConfigurationBuilder().SetBasePath(basePath) + .AddJsonFile("appsettings.json", false, true).Build(); + services.AddSingleton(_ => configuration); + services.AddDbContext((serviceProvider, options) => - { - options - .AddInterceptors(serviceProvider - .GetRequiredService< - SecondLevelCacheInterceptor>()) - .UseSqlServer(GetConnectionString(basePath, configuration)) - .LogTo(sql => Console.WriteLine(sql)); - }); + { + options.AddInterceptors(serviceProvider.GetRequiredService()) + .UseSqlServer(GetConnectionString(basePath, configuration)).LogTo(sql => Console.WriteLine(sql)); + }); return services.BuildServiceProvider(); } public static string GetConnectionString(string basePath, IConfigurationRoot configuration) { - var testsFolder = basePath.Split(new[] { "\\Issues\\" }, StringSplitOptions.RemoveEmptyEntries)[0]; + var testsFolder = basePath.Split(new[] + { + "\\Issues\\" + }, StringSplitOptions.RemoveEmptyEntries)[0]; + var contentRootPath = Path.Combine(testsFolder, "Issues", "Issue123WithMessagePack"); var connectionString = configuration["ConnectionStrings:ApplicationDbContextConnection"]; + if (connectionString.Contains("%CONTENTROOTPATH%")) { connectionString = connectionString.Replace("%CONTENTROOTPATH%", contentRootPath); } Console.WriteLine($"Using {connectionString}"); + return connectionString; } } @@ -129,9 +131,8 @@ private DBNullFormatter() } public void Serialize(ref MessagePackWriter writer, DBNull value, MessagePackSerializerOptions options) - { - writer.WriteNil(); - } + => writer.WriteNil(); - public DBNull Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) => DBNull.Value; + public DBNull Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) + => DBNull.Value; } \ No newline at end of file diff --git a/src/Tests/Issues/Issue125EF5x/EFServiceProvider.cs b/src/Tests/Issues/Issue125EF5x/EFServiceProvider.cs index 951a354..6ce0b84 100644 --- a/src/Tests/Issues/Issue125EF5x/EFServiceProvider.cs +++ b/src/Tests/Issues/Issue125EF5x/EFServiceProvider.cs @@ -22,7 +22,8 @@ public static class EFServiceProvider /// public static IServiceProvider Instance { get; } = _serviceProviderBuilder.Value; - public static T GetRequiredService() => Instance.GetRequiredService(); + public static T GetRequiredService() + => Instance.GetRequiredService(); public static void RunInContext(Action action) { @@ -46,64 +47,70 @@ private static IServiceProvider getServiceProvider() services.AddLogging(cfg => cfg.AddConsole().AddDebug().SetMinimumLevel(LogLevel.Debug)); const string providerName = "Redis1"; + services.AddEasyCaching(o => - { - o.UseRedis(cfg => - { - cfg.SerializerName = "Pack"; - cfg.DBConfig.Endpoints.Add(new ServerEndPoint("127.0.0.1", 6379)); - cfg.DBConfig.AllowAdmin = true; - cfg.DBConfig.ConnectionTimeout = 10000; - }, providerName); - o.WithMessagePack( /*so => - { - so.EnableCustomResolver = true; - so.CustomResolvers = CompositeResolver.Create(new MessagePack.IFormatterResolver[] - { - NativeDateTimeResolver.Instance, - ContractlessStandardResolver.Instance, - StandardResolverAllowPrivate.Instance - }); - },*/ - "Pack"); - }); + { + o.UseRedis(cfg => + { + cfg.SerializerName = "Pack"; + cfg.DBConfig.Endpoints.Add(new ServerEndPoint("127.0.0.1", 6379)); + cfg.DBConfig.AllowAdmin = true; + cfg.DBConfig.ConnectionTimeout = 10000; + }, providerName); + + o.WithMessagePack( /*so => +{ +so.EnableCustomResolver = true; +so.CustomResolvers = CompositeResolver.Create(new MessagePack.IFormatterResolver[] +{ + NativeDateTimeResolver.Instance, + ContractlessStandardResolver.Instance, + StandardResolverAllowPrivate.Instance +}); +},*/ + "Pack"); + }); + services.AddEFSecondLevelCache(o => - { - o.UseEasyCachingCoreProvider(providerName, false).DisableLogging(); - o.CacheAllQueries(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(10)); - }); + { + o.UseEasyCachingCoreProvider(providerName).ConfigureLogging(true); + o.CacheAllQueries(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(10)); + }); var basePath = Directory.GetCurrentDirectory(); Console.WriteLine($"Using `{basePath}` as the ContentRootPath"); - var configuration = new ConfigurationBuilder() - .SetBasePath(basePath) - .AddJsonFile("appsettings.json", false, true) - .Build(); + + var configuration = new ConfigurationBuilder().SetBasePath(basePath) + .AddJsonFile("appsettings.json", false, true).Build(); + services.AddSingleton(_ => configuration); + services.AddDbContext((serviceProvider, options) => - { - options - .AddInterceptors(serviceProvider - .GetRequiredService< - SecondLevelCacheInterceptor>()) - .UseSqlServer(GetConnectionString(basePath, configuration)) - .LogTo(sql => Console.WriteLine(sql)); - }); + { + options.AddInterceptors(serviceProvider.GetRequiredService()) + .UseSqlServer(GetConnectionString(basePath, configuration)).LogTo(sql => Console.WriteLine(sql)); + }); return services.BuildServiceProvider(); } public static string GetConnectionString(string basePath, IConfigurationRoot configuration) { - var testsFolder = basePath.Split(new[] { "\\Issues\\" }, StringSplitOptions.RemoveEmptyEntries)[0]; + var testsFolder = basePath.Split(new[] + { + "\\Issues\\" + }, StringSplitOptions.RemoveEmptyEntries)[0]; + var contentRootPath = Path.Combine(testsFolder, "Issues", "Issue125EF5x"); var connectionString = configuration["ConnectionStrings:ApplicationDbContextConnection"]; + if (connectionString.Contains("%CONTENTROOTPATH%")) { connectionString = connectionString.Replace("%CONTENTROOTPATH%", contentRootPath); } Console.WriteLine($"Using {connectionString}"); + return connectionString; } } \ No newline at end of file diff --git a/src/Tests/Issues/Issue12PostgreSql/EFServiceProvider.cs b/src/Tests/Issues/Issue12PostgreSql/EFServiceProvider.cs index 7e84bde..3afcc3e 100644 --- a/src/Tests/Issues/Issue12PostgreSql/EFServiceProvider.cs +++ b/src/Tests/Issues/Issue12PostgreSql/EFServiceProvider.cs @@ -25,7 +25,8 @@ public static class EFServiceProvider /// public static IServiceProvider Instance { get; } = _serviceProviderBuilder.Value; - public static T GetRequiredService() => Instance.GetRequiredService(); + public static T GetRequiredService() + => Instance.GetRequiredService(); public static void RunInContext(Action action) { @@ -50,63 +51,56 @@ private static IServiceProvider getServiceProvider() var basePath = Directory.GetCurrentDirectory(); Console.WriteLine($"Using `{basePath}` as the ContentRootPath"); - var configuration = new ConfigurationBuilder() - .SetBasePath(basePath) - .AddJsonFile("appsettings.json", false, true) - .Build(); + + var configuration = new ConfigurationBuilder().SetBasePath(basePath) + .AddJsonFile("appsettings.json", false, true).Build(); + services.AddSingleton(_ => configuration); const string providerName = "Redis1"; + services.AddEasyCaching(o => - { - o.UseRedis(cfg => - { - cfg.SerializerName = "Pack"; - cfg.DBConfig.Endpoints.Add(new ServerEndPoint("127.0.0.1", 6379)); - cfg.DBConfig.AllowAdmin = true; - cfg.DBConfig.ConnectionTimeout = 10000; - }, - providerName); - o.WithMessagePack(so => - { - so.EnableCustomResolver = true; - so.CustomResolvers = CompositeResolver.Create( - new IMessagePackFormatter[] - { - DBNullFormatter - .Instance, // This is necessary for the null values - }, - new IFormatterResolver[] - { - NativeDateTimeResolver.Instance, - ContractlessStandardResolver.Instance, - StandardResolverAllowPrivate.Instance, - TypelessContractlessStandardResolver.Instance, - DynamicGenericResolver.Instance, - }); - }, - "Pack"); - }); + { + o.UseRedis(cfg => + { + cfg.SerializerName = "Pack"; + cfg.DBConfig.Endpoints.Add(new ServerEndPoint("127.0.0.1", 6379)); + cfg.DBConfig.AllowAdmin = true; + cfg.DBConfig.ConnectionTimeout = 10000; + }, providerName); + + o.WithMessagePack(so => + { + so.EnableCustomResolver = true; + + so.CustomResolvers = CompositeResolver.Create(new IMessagePackFormatter[] + { + DBNullFormatter.Instance // This is necessary for the null values + }, new IFormatterResolver[] + { + NativeDateTimeResolver.Instance, ContractlessStandardResolver.Instance, + StandardResolverAllowPrivate.Instance, TypelessContractlessStandardResolver.Instance, + DynamicGenericResolver.Instance + }); + }, "Pack"); + }); services.AddEFSecondLevelCache(o => - { - o.UseEasyCachingCoreProvider(providerName).DisableLogging(); - o.CacheAllQueries(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(10)); - o.UseCacheKeyPrefix("EF_"); - // Fallback on db if the caching provider (redis) is down. - o.UseDbCallsIfCachingProviderIsDown(TimeSpan.FromMinutes(1)); - }); + { + o.UseEasyCachingCoreProvider(providerName).ConfigureLogging(true); + o.CacheAllQueries(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(10)); + o.UseCacheKeyPrefix("EF_"); + + // Fallback on db if the caching provider (redis) is down. + o.UseDbCallsIfCachingProviderIsDown(TimeSpan.FromMinutes(1)); + }); services.AddDbContext((serviceProvider, optionsBuilder) => - { - optionsBuilder - .AddInterceptors(serviceProvider - .GetRequiredService< - SecondLevelCacheInterceptor>()) - .UseNpgsql(configuration - ["ConnectionStrings:ApplicationDbContextConnection"]) - .LogTo(sql => Console.WriteLine(sql)); - }); + { + optionsBuilder.AddInterceptors(serviceProvider.GetRequiredService()) + .UseNpgsql(configuration["ConnectionStrings:ApplicationDbContextConnection"]) + .LogTo(sql => Console.WriteLine(sql)); + }); return services.BuildServiceProvider(); } @@ -121,9 +115,8 @@ private DBNullFormatter() } public void Serialize(ref MessagePackWriter writer, DBNull value, MessagePackSerializerOptions options) - { - writer.WriteNil(); - } + => writer.WriteNil(); - public DBNull Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) => DBNull.Value; + public DBNull Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) + => DBNull.Value; } \ No newline at end of file diff --git a/src/Tests/Issues/Issue154/EFServiceProvider.cs b/src/Tests/Issues/Issue154/EFServiceProvider.cs index 0512c3e..16f8e40 100644 --- a/src/Tests/Issues/Issue154/EFServiceProvider.cs +++ b/src/Tests/Issues/Issue154/EFServiceProvider.cs @@ -1,87 +1,89 @@ using System; -using Microsoft.Extensions.DependencyInjection; -using System.Threading; using System.IO; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Logging; +using System.Threading; using System.Threading.Tasks; -using Issue154.DataLayer; using EFCoreSecondLevelCacheInterceptor; +using Issue154.DataLayer; using Microsoft.EntityFrameworkCore; -using CacheManager.Core; -using Newtonsoft.Json; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; + +namespace Issue154; -namespace Issue154 +public static class EFServiceProvider { - public static class EFServiceProvider + private static readonly Lazy _serviceProviderBuilder = + new(getServiceProvider, LazyThreadSafetyMode.ExecutionAndPublication); + + /// + /// A lazy loaded thread-safe singleton + /// + public static IServiceProvider Instance { get; } = _serviceProviderBuilder.Value; + + public static T GetRequiredService() + => Instance.GetRequiredService(); + + public static void RunInContext(Action action) + { + using var serviceScope = GetRequiredService().CreateScope(); + using var context = serviceScope.ServiceProvider.GetRequiredService(); + action(context); + } + + public static async Task RunInContextAsync(Func action) { - private static readonly Lazy _serviceProviderBuilder = - new Lazy(getServiceProvider, LazyThreadSafetyMode.ExecutionAndPublication); + using var serviceScope = GetRequiredService().CreateScope(); + using var context = serviceScope.ServiceProvider.GetRequiredService(); + await action(context); + } - /// - /// A lazy loaded thread-safe singleton - /// - public static IServiceProvider Instance { get; } = _serviceProviderBuilder.Value; + private static IServiceProvider getServiceProvider() + { + var services = new ServiceCollection(); + services.AddOptions(); - public static T GetRequiredService() - { - return Instance.GetRequiredService(); - } + services.AddLogging(cfg => cfg.AddConsole().AddDebug()) + .Configure(cfg => cfg.MinLevel = LogLevel.Debug); - public static void RunInContext(Action action) - { - using var serviceScope = GetRequiredService().CreateScope(); - using var context = serviceScope.ServiceProvider.GetRequiredService(); - action(context); - } + var basePath = Directory.GetCurrentDirectory(); + Console.WriteLine($"Using `{basePath}` as the ContentRootPath"); + + var configuration = new ConfigurationBuilder().SetBasePath(basePath) + .AddJsonFile("appsettings.json", false, true).Build(); + + services.AddSingleton(_ => configuration); + + services.AddEFSecondLevelCache(options + => options.UseMemoryCacheProvider(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(5)) + .ConfigureLogging(true)); - public static async Task RunInContextAsync(Func action) + services.AddDbContext((serviceProvider, optionsBuilder) => { - using var serviceScope = GetRequiredService().CreateScope(); - using var context = serviceScope.ServiceProvider.GetRequiredService(); - await action(context); - } + optionsBuilder.AddInterceptors(serviceProvider.GetRequiredService()) + .UseSqlite(GetConnectionString(basePath, configuration)); + }); + + return services.BuildServiceProvider(); + } - private static IServiceProvider getServiceProvider() + public static string GetConnectionString(string basePath, IConfigurationRoot configuration) + { + var testsFolder = basePath.Split(new[] { - var services = new ServiceCollection(); - services.AddOptions(); - - services.AddLogging(cfg => cfg.AddConsole().AddDebug()).Configure(cfg => cfg.MinLevel = LogLevel.Debug); - - var basePath = Directory.GetCurrentDirectory(); - Console.WriteLine($"Using `{basePath}` as the ContentRootPath"); - var configuration = new Microsoft.Extensions.Configuration.ConfigurationBuilder() - .SetBasePath(basePath) - .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) - .Build(); - services.AddSingleton(_ => configuration); - - services.AddEFSecondLevelCache(options => - options.UseMemoryCacheProvider(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(5)).DisableLogging(false) - ); - - services.AddDbContext((serviceProvider, optionsBuilder) => - { - optionsBuilder - .AddInterceptors(serviceProvider.GetRequiredService()) - .UseSqlite(GetConnectionString(basePath, configuration)); - }); - - return services.BuildServiceProvider(); - } + "\\Issues\\" + }, StringSplitOptions.RemoveEmptyEntries)[0]; + + var contentRootPath = Path.Combine(testsFolder, "Issues", "Issue154"); + var connectionString = configuration["ConnectionStrings:ApplicationDbContextConnection"]; - public static string GetConnectionString(string basePath, IConfigurationRoot configuration) + if (connectionString.Contains("%CONTENTROOTPATH%")) { - var testsFolder = basePath.Split(new[] { "\\Issues\\" }, StringSplitOptions.RemoveEmptyEntries)[0]; - var contentRootPath = Path.Combine(testsFolder, "Issues", "Issue154"); - var connectionString = configuration["ConnectionStrings:ApplicationDbContextConnection"]; - if (connectionString.Contains("%CONTENTROOTPATH%")) - { - connectionString = connectionString.Replace("%CONTENTROOTPATH%", contentRootPath); - } - Console.WriteLine($"Using {connectionString}"); - return connectionString; + connectionString = connectionString.Replace("%CONTENTROOTPATH%", contentRootPath); } + + Console.WriteLine($"Using {connectionString}"); + + return connectionString; } } \ No newline at end of file diff --git a/src/Tests/Issues/Issue192/EFServiceProvider.cs b/src/Tests/Issues/Issue192/EFServiceProvider.cs index 1a39389..09cc8fe 100644 --- a/src/Tests/Issues/Issue192/EFServiceProvider.cs +++ b/src/Tests/Issues/Issue192/EFServiceProvider.cs @@ -21,7 +21,8 @@ public static class EFServiceProvider /// public static IServiceProvider Instance { get; } = _serviceProviderBuilder.Value; - public static T GetRequiredService() => Instance.GetRequiredService(); + public static T GetRequiredService() + => Instance.GetRequiredService(); public static void RunInContext(Action action) { @@ -45,42 +46,45 @@ private static IServiceProvider getServiceProvider() services.AddLogging(cfg => cfg.AddConsole().AddDebug().SetMinimumLevel(LogLevel.Debug)); services.AddEFSecondLevelCache(o => - { - o.UseMemoryCacheProvider().DisableLogging(); - o.CacheAllQueries(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(10)); - }); + { + o.UseMemoryCacheProvider().ConfigureLogging(true); + o.CacheAllQueries(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(10)); + }); var basePath = Directory.GetCurrentDirectory(); Console.WriteLine($"Using `{basePath}` as the ContentRootPath"); - var configuration = new ConfigurationBuilder() - .SetBasePath(basePath) - .AddJsonFile("appsettings.json", false, true) - .Build(); + + var configuration = new ConfigurationBuilder().SetBasePath(basePath) + .AddJsonFile("appsettings.json", false, true).Build(); + services.AddSingleton(_ => configuration); + services.AddDbContext((serviceProvider, options) => - { - options - .AddInterceptors(serviceProvider - .GetRequiredService< - SecondLevelCacheInterceptor>()) - .UseSqlServer(GetConnectionString(basePath, configuration)) - .LogTo(sql => Console.WriteLine(sql)); - }); + { + options.AddInterceptors(serviceProvider.GetRequiredService()) + .UseSqlServer(GetConnectionString(basePath, configuration)).LogTo(sql => Console.WriteLine(sql)); + }); return services.BuildServiceProvider(); } public static string GetConnectionString(string basePath, IConfigurationRoot configuration) { - var testsFolder = basePath.Split(new[] { "\\Issues\\" }, StringSplitOptions.RemoveEmptyEntries)[0]; + var testsFolder = basePath.Split(new[] + { + "\\Issues\\" + }, StringSplitOptions.RemoveEmptyEntries)[0]; + var contentRootPath = Path.Combine(testsFolder, "Issues", "Issue192"); var connectionString = configuration["ConnectionStrings:ApplicationDbContextConnection"]; + if (connectionString.Contains("%CONTENTROOTPATH%")) { connectionString = connectionString.Replace("%CONTENTROOTPATH%", contentRootPath); } Console.WriteLine($"Using {connectionString}"); + return connectionString; } } \ No newline at end of file diff --git a/src/Tests/Issues/Issue9SQLiteInt32/EFServiceProvider.cs b/src/Tests/Issues/Issue9SQLiteInt32/EFServiceProvider.cs index 6ba023d..40e9f2f 100644 --- a/src/Tests/Issues/Issue9SQLiteInt32/EFServiceProvider.cs +++ b/src/Tests/Issues/Issue9SQLiteInt32/EFServiceProvider.cs @@ -1,122 +1,123 @@ using System; -using Microsoft.Extensions.DependencyInjection; -using System.Threading; using System.IO; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Logging; +using System.Threading; using System.Threading.Tasks; -using Issue9SQLiteInt32.DataLayer; +using CacheManager.Core; using EFCoreSecondLevelCacheInterceptor; +using Issue9SQLiteInt32.DataLayer; using Microsoft.EntityFrameworkCore; -using CacheManager.Core; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; using Newtonsoft.Json; +using ConfigurationBuilder = Microsoft.Extensions.Configuration.ConfigurationBuilder; -namespace Issue9SQLiteInt32 +namespace Issue9SQLiteInt32; + +public static class EFServiceProvider { - public static class EFServiceProvider + private static readonly Lazy _serviceProviderBuilder = + new(getServiceProvider, LazyThreadSafetyMode.ExecutionAndPublication); + + /// + /// A lazy loaded thread-safe singleton + /// + public static IServiceProvider Instance { get; } = _serviceProviderBuilder.Value; + + public static T GetRequiredService() + => Instance.GetRequiredService(); + + public static void RunInContext(Action action) { - private static readonly Lazy _serviceProviderBuilder = - new Lazy(getServiceProvider, LazyThreadSafetyMode.ExecutionAndPublication); + using var serviceScope = GetRequiredService().CreateScope(); + using var context = serviceScope.ServiceProvider.GetRequiredService(); + action(context); + } - /// - /// A lazy loaded thread-safe singleton - /// - public static IServiceProvider Instance { get; } = _serviceProviderBuilder.Value; + public static async Task RunInContextAsync(Func action) + { + using var serviceScope = GetRequiredService().CreateScope(); + using var context = serviceScope.ServiceProvider.GetRequiredService(); + await action(context); + } - public static T GetRequiredService() - { - return Instance.GetRequiredService(); - } + private static IServiceProvider getServiceProvider() + { + var services = new ServiceCollection(); + services.AddOptions(); - public static void RunInContext(Action action) - { - using var serviceScope = GetRequiredService().CreateScope(); - using var context = serviceScope.ServiceProvider.GetRequiredService(); - action(context); - } + services.AddLogging(cfg => cfg.AddConsole().AddDebug()); + + var basePath = Directory.GetCurrentDirectory(); + Console.WriteLine($"Using `{basePath}` as the ContentRootPath"); + + var configuration = new ConfigurationBuilder().SetBasePath(basePath) + .AddJsonFile("appsettings.json", false, true).Build(); + + services.AddSingleton(_ => configuration); + + services.AddEFSecondLevelCache(options + => options.UseMemoryCacheProvider(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(5)) + .ConfigureLogging(true) + + //options.UseCacheManagerCoreProvider() + ); - public static async Task RunInContextAsync(Func action) + addCacheManagerCoreRedis(services); + + services.AddDbContext((serviceProvider, optionsBuilder) => { - using var serviceScope = GetRequiredService().CreateScope(); - using var context = serviceScope.ServiceProvider.GetRequiredService(); - await action(context); - } + optionsBuilder.AddInterceptors(serviceProvider.GetRequiredService()) + .UseSqlite(GetConnectionString(basePath, configuration)); + }); + + return services.BuildServiceProvider(); + } - private static IServiceProvider getServiceProvider() + public static string GetConnectionString(string basePath, IConfigurationRoot configuration) + { + var testsFolder = basePath.Split(new[] { - var services = new ServiceCollection(); - services.AddOptions(); - - services.AddLogging(cfg => cfg.AddConsole().AddDebug()); - - var basePath = Directory.GetCurrentDirectory(); - Console.WriteLine($"Using `{basePath}` as the ContentRootPath"); - var configuration = new Microsoft.Extensions.Configuration.ConfigurationBuilder() - .SetBasePath(basePath) - .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) - .Build(); - services.AddSingleton(_ => configuration); - - services.AddEFSecondLevelCache(options => - options.UseMemoryCacheProvider(CacheExpirationMode.Absolute, TimeSpan.FromMinutes(5)).DisableLogging(false) - //options.UseCacheManagerCoreProvider() - ); - addCacheManagerCoreRedis(services); - - services.AddDbContext((serviceProvider, optionsBuilder) => - { - optionsBuilder - .AddInterceptors(serviceProvider.GetRequiredService()) - .UseSqlite(GetConnectionString(basePath, configuration)); - }); + "\\Issues\\" + }, StringSplitOptions.RemoveEmptyEntries)[0]; - return services.BuildServiceProvider(); - } + var contentRootPath = Path.Combine(testsFolder, "Issues", "Issue9SQLiteInt32"); + var connectionString = configuration["ConnectionStrings:ApplicationDbContextConnection"]; - public static string GetConnectionString(string basePath, IConfigurationRoot configuration) + if (connectionString.Contains("%CONTENTROOTPATH%")) { - var testsFolder = basePath.Split(new[] { "\\Issues\\" }, StringSplitOptions.RemoveEmptyEntries)[0]; - var contentRootPath = Path.Combine(testsFolder, "Issues", "Issue9SQLiteInt32"); - var connectionString = configuration["ConnectionStrings:ApplicationDbContextConnection"]; - if (connectionString.Contains("%CONTENTROOTPATH%")) - { - connectionString = connectionString.Replace("%CONTENTROOTPATH%", contentRootPath); - } - Console.WriteLine($"Using {connectionString}"); - return connectionString; + connectionString = connectionString.Replace("%CONTENTROOTPATH%", contentRootPath); } - private static void addCacheManagerCoreRedis(ServiceCollection services) + Console.WriteLine($"Using {connectionString}"); + + return connectionString; + } + + private static void addCacheManagerCoreRedis(ServiceCollection services) + { + var jss = new JsonSerializerSettings { - var jss = new JsonSerializerSettings - { - NullValueHandling = NullValueHandling.Ignore, - ReferenceLoopHandling = ReferenceLoopHandling.Ignore, - TypeNameHandling = TypeNameHandling.Auto - }; - - const string redisConfigurationKey = "redis"; - services.AddSingleton(typeof(ICacheManagerConfiguration), - new CacheManager.Core.ConfigurationBuilder() - .WithJsonSerializer(serializationSettings: jss, deserializationSettings: jss) - .WithUpdateMode(CacheUpdateMode.Up) - .WithRedisConfiguration(redisConfigurationKey, config => - { - config.WithAllowAdmin() - .WithDatabase(0) - .WithEndpoint("localhost", 6379) - // Enables keyspace notifications to react on eviction/expiration of items. - // Make sure that all servers are configured correctly and 'notify-keyspace-events' is at least set to 'Exe', otherwise CacheManager will not retrieve any events. - // See https://redis.io/topics/notifications#configuration for configuration details. - .EnableKeyspaceEvents(); - }) - .WithMaxRetries(100) - .WithRetryTimeout(50) - .WithRedisCacheHandle(redisConfigurationKey) - .DisablePerformanceCounters() - .DisableStatistics() - .Build()); - services.AddSingleton(typeof(ICacheManager<>), typeof(BaseCacheManager<>)); - } + NullValueHandling = NullValueHandling.Ignore, + ReferenceLoopHandling = ReferenceLoopHandling.Ignore, + TypeNameHandling = TypeNameHandling.Auto + }; + + const string redisConfigurationKey = "redis"; + + services.AddSingleton(typeof(ICacheManagerConfiguration), new CacheManager.Core.ConfigurationBuilder() + .WithJsonSerializer(jss, jss).WithUpdateMode(CacheUpdateMode.Up).WithRedisConfiguration( + redisConfigurationKey, config => + { + config.WithAllowAdmin().WithDatabase(0).WithEndpoint("localhost", 6379) + + // Enables keyspace notifications to react on eviction/expiration of items. + // Make sure that all servers are configured correctly and 'notify-keyspace-events' is at least set to 'Exe', otherwise CacheManager will not retrieve any events. + // See https://redis.io/topics/notifications#configuration for configuration details. + .EnableKeyspaceEvents(); + }).WithMaxRetries(100).WithRetryTimeout(50).WithRedisCacheHandle(redisConfigurationKey) + .DisablePerformanceCounters().DisableStatistics().Build()); + + services.AddSingleton(typeof(ICacheManager<>), typeof(BaseCacheManager<>)); } } \ No newline at end of file