From 2aecefbd2b6a48bef55d8264b667aadf4489f19b Mon Sep 17 00:00:00 2001 From: Savorboard Date: Mon, 10 Jan 2022 15:56:05 +0800 Subject: [PATCH] Add a check for using Cap in DbContext and throw exception prompt. #1067 #539 --- src/DotNetCore.CAP.MySql/CAP.MySqlOptions.cs | 7 +++++++ src/DotNetCore.CAP.PostgreSql/CAP.PostgreSqlOptions.cs | 9 ++++++++- src/DotNetCore.CAP.SqlServer/CAP.SqlServerOptions.cs | 7 +++++++ src/DotNetCore.CAP/Internal/Helper.cs | 9 +++++++++ src/DotNetCore.CAP/Internal/IBootstrapper.Default.cs | 6 +++++- 5 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/DotNetCore.CAP.MySql/CAP.MySqlOptions.cs b/src/DotNetCore.CAP.MySql/CAP.MySqlOptions.cs index a6f78f9..9cea783 100644 --- a/src/DotNetCore.CAP.MySql/CAP.MySqlOptions.cs +++ b/src/DotNetCore.CAP.MySql/CAP.MySqlOptions.cs @@ -1,6 +1,8 @@ // Copyright (c) .NET Core Community. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. +using System; +using DotNetCore.CAP.Internal; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; @@ -29,6 +31,11 @@ namespace DotNetCore.CAP { if (options.DbContextType != null) { + if (Helper.IsUsingType(options.DbContextType)) + { + throw new InvalidOperationException("We detected that you are using ICapPublisher in DbContext, please change the configuration to use the storage extension directly to avoid circular references! eg: x.UseMySql()"); + } + using var scope = _serviceScopeFactory.CreateScope(); var provider = scope.ServiceProvider; using var dbContext = (DbContext)provider.GetRequiredService(options.DbContextType); diff --git a/src/DotNetCore.CAP.PostgreSql/CAP.PostgreSqlOptions.cs b/src/DotNetCore.CAP.PostgreSql/CAP.PostgreSqlOptions.cs index bcaf405..922abc4 100644 --- a/src/DotNetCore.CAP.PostgreSql/CAP.PostgreSqlOptions.cs +++ b/src/DotNetCore.CAP.PostgreSql/CAP.PostgreSqlOptions.cs @@ -1,6 +1,8 @@ // Copyright (c) .NET Core Community. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. +using System; +using DotNetCore.CAP.Internal; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; @@ -28,7 +30,12 @@ namespace DotNetCore.CAP public void Configure(PostgreSqlOptions options) { if (options.DbContextType == null) return; - + + if (Helper.IsUsingType(options.DbContextType)) + { + throw new InvalidOperationException("We detected that you are using ICapPublisher in DbContext, please change the configuration to use the storage extension directly to avoid circular references! eg: x.UsePostgreSql()"); + } + using var scope = _serviceScopeFactory.CreateScope(); var provider = scope.ServiceProvider; using var dbContext = (DbContext) provider.GetRequiredService(options.DbContextType); diff --git a/src/DotNetCore.CAP.SqlServer/CAP.SqlServerOptions.cs b/src/DotNetCore.CAP.SqlServer/CAP.SqlServerOptions.cs index d92cb42..60d5a38 100644 --- a/src/DotNetCore.CAP.SqlServer/CAP.SqlServerOptions.cs +++ b/src/DotNetCore.CAP.SqlServer/CAP.SqlServerOptions.cs @@ -1,6 +1,8 @@ // Copyright (c) .NET Core Community. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. +using System; +using DotNetCore.CAP.Internal; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; @@ -30,6 +32,11 @@ namespace DotNetCore.CAP { if (options.DbContextType == null) return; + if (Helper.IsUsingType(options.DbContextType)) + { + throw new InvalidOperationException("We detected that you are using ICapPublisher in DbContext, please change the configuration to use the storage extension directly to avoid circular references! eg: x.UseSqlServer()"); + } + using var scope = _serviceScopeFactory.CreateScope(); var provider = scope.ServiceProvider; using var dbContext = (DbContext)provider.GetRequiredService(options.DbContextType); diff --git a/src/DotNetCore.CAP/Internal/Helper.cs b/src/DotNetCore.CAP/Internal/Helper.cs index 402a007..89ea485 100644 --- a/src/DotNetCore.CAP/Internal/Helper.cs +++ b/src/DotNetCore.CAP/Internal/Helper.cs @@ -3,6 +3,7 @@ using System; using System.ComponentModel; +using System.Linq; using System.Reflection; using System.Text.RegularExpressions; @@ -66,6 +67,14 @@ namespace DotNetCore.CAP.Internal return Regex.IsMatch(name, pattern) ? Regex.Replace(name, pattern, "_") : name; } + public static bool IsUsingType(in Type type) + { + BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | + BindingFlags.Static | BindingFlags.Instance | + BindingFlags.DeclaredOnly; + return type.GetFields(flags).Any(x => x.FieldType == typeof(T)); + } + public static bool IsInnerIP(string ipAddress) { var ipNum = GetIpNum(ipAddress); diff --git a/src/DotNetCore.CAP/Internal/IBootstrapper.Default.cs b/src/DotNetCore.CAP/Internal/IBootstrapper.Default.cs index 9ed2cf0..674c508 100644 --- a/src/DotNetCore.CAP/Internal/IBootstrapper.Default.cs +++ b/src/DotNetCore.CAP/Internal/IBootstrapper.Default.cs @@ -19,7 +19,7 @@ namespace DotNetCore.CAP.Internal { private readonly IServiceProvider _serviceProvider; private readonly ILogger _logger; - private readonly CancellationTokenSource _cts = new (); + private readonly CancellationTokenSource _cts = new(); private bool _disposed; private IEnumerable _processors = default!; @@ -43,6 +43,10 @@ namespace DotNetCore.CAP.Internal } catch (Exception e) { + if (e is InvalidOperationException) + { + throw; + } _logger.LogError(e, "Initializing the storage structure failed!"); }