diff --git a/AElf.ExceptionHandler.ABP/AElf.ExceptionHandler.ABP.csproj b/AElf.ExceptionHandler.ABP/AElf.ExceptionHandler.ABP.csproj
index 9c534c3..20375f2 100644
--- a/AElf.ExceptionHandler.ABP/AElf.ExceptionHandler.ABP.csproj
+++ b/AElf.ExceptionHandler.ABP/AElf.ExceptionHandler.ABP.csproj
@@ -16,9 +16,15 @@
AElf.ExceptionHandler.ABP
+
+ $(DefineConstants);ABP_VERSION_8_2_0
+
+
-
-
+
+
+
+
@@ -31,4 +37,13 @@
+
+
+ ..\..\..\..\..\..\usr\local\share\dotnet\shared\Microsoft.AspNetCore.App\8.0.6\Microsoft.AspNetCore.Mvc.Abstractions.dll
+
+
+ ..\..\..\..\..\..\usr\local\share\dotnet\shared\Microsoft.AspNetCore.App\8.0.6\Microsoft.AspNetCore.Mvc.Core.dll
+
+
+
diff --git a/AElf.ExceptionHandler.ABP/AOPExceptionModule.cs b/AElf.ExceptionHandler.ABP/AOPExceptionModule.cs
index fb55094..86bd151 100644
--- a/AElf.ExceptionHandler.ABP/AOPExceptionModule.cs
+++ b/AElf.ExceptionHandler.ABP/AOPExceptionModule.cs
@@ -1,29 +1,45 @@
using System.Reflection;
using AElf.ExceptionHandler.Extensions;
using Microsoft.Extensions.DependencyInjection;
+using Volo.Abp.Castle;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.DynamicProxy;
using Volo.Abp.Modularity;
namespace AElf.ExceptionHandler.ABP;
+[DependsOn(
+ typeof(AbpCastleCoreModule)
+)]
public class AOPExceptionModule : AbpModule
{
- public override void ConfigureServices(ServiceConfigurationContext context)
+ public override void PreConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddExceptionHandler();
- context.Services.AddTransient();
-
- context.Services.OnRegistered(options =>
+ }
+
+ public override void PostConfigureServices(ServiceConfigurationContext context)
+ {
+ base.PostConfigureServices(context);
+
+ var builder = context.Services.GetContainerBuilder();
+
+ context.Services.OnRegistered(RegisterExceptionHandlerIfNeeded);
+
+ AutofacRegistration.Register(builder, context.Services, null);
+ }
+
+ private static void RegisterExceptionHandlerIfNeeded(IOnServiceRegistredContext context)
+ {
+ if(ShouldIntercept(context.ImplementationType))
{
- var methodInfos = options.ImplementationType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
- // Check if any of the class methods is decorated with the ExceptionHandlerAttribute
- foreach (var methodInfo in methodInfos)
- {
- if (methodInfo.IsDefined(typeof(ExceptionHandlerAttribute), true))
- {
- var result = options.Interceptors.TryAdd();
- break;
- }
- }
- });
+ context.Interceptors.TryAdd();
+ }
+ }
+
+ private static bool ShouldIntercept(Type type)
+ {
+ return ExceptionHandlerHelper.IsExceptionHandlerType(type.GetTypeInfo());
+ //return !DynamicProxyIgnoreTypes.Contains(type) && ExceptionHandlerHelper.IsExceptionHandlerType(type.GetTypeInfo());
}
}
\ No newline at end of file
diff --git a/AElf.ExceptionHandler.ABP/AutofacRegistration.cs b/AElf.ExceptionHandler.ABP/AutofacRegistration.cs
new file mode 100644
index 0000000..be98e1c
--- /dev/null
+++ b/AElf.ExceptionHandler.ABP/AutofacRegistration.cs
@@ -0,0 +1,395 @@
+// This software is part of the Autofac IoC container
+// Copyright © 2015 Autofac Contributors
+// https://autofac.org
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+
+using System;
+using System.Diagnostics.CodeAnalysis;
+using System.Reflection;
+using Autofac;
+using Autofac.Builder;
+using Autofac.Core;
+using Autofac.Core.Activators;
+using Autofac.Core.Activators.Delegate;
+using Autofac.Core.Activators.Reflection;
+using Autofac.Core.Resolving.Pipeline;
+using Autofac.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection;
+using Volo.Abp;
+using Volo.Abp.Modularity;
+
+namespace AElf.ExceptionHandler.ABP;
+
+///
+/// Extension methods for registering ASP.NET Core dependencies with Autofac.
+///
+public static class AutofacRegistration
+{
+ ///
+ /// Populates the Autofac container builder with the set of registered service descriptors
+ /// and makes and
+ /// available in the container.
+ ///
+ ///
+ /// The into which the registrations should be made.
+ ///
+ ///
+ /// A container builder that can be used to create an .
+ ///
+ public static void Populate(
+ this ContainerBuilder builder,
+ IServiceCollection services)
+ {
+ Populate(builder, services, null);
+ }
+
+ ///
+ /// Populates the Autofac container builder with the set of registered service descriptors
+ /// and makes and
+ /// available in the container. Using this overload is incompatible with the ASP.NET Core
+ /// support for .
+ ///
+ ///
+ /// The into which the registrations should be made.
+ ///
+ ///
+ /// A container builder that can be used to create an .
+ ///
+ ///
+ /// If provided and not then all registrations with lifetime are registered
+ /// using
+ /// with provided
+ /// instead of using .
+ ///
+ ///
+ ///
+ /// Specifying a addresses a specific case where you have
+ /// an application that uses Autofac but where you need to isolate a set of services in a child scope. For example,
+ /// if you have a large application that self-hosts ASP.NET Core items, you may want to isolate the ASP.NET
+ /// Core registrations in a child lifetime scope so they don't show up for the rest of the application.
+ /// This overload allows that. Note it is the developer's responsibility to execute this and create an
+ /// using the child lifetime scope.
+ ///
+ ///
+ public static void Populate(
+ this ContainerBuilder builder,
+ IServiceCollection services,
+ object? lifetimeScopeTagForSingletons)
+ {
+ if (services == null)
+ {
+ throw new ArgumentNullException(nameof(services));
+ }
+
+ builder.RegisterType()
+ .As()
+ .As()
+ .As()
+ .As()
+ .ExternallyOwned();
+
+ var autofacServiceScopeFactory = typeof(AutofacServiceProvider).Assembly.GetType("Autofac.Extensions.DependencyInjection.AutofacServiceScopeFactory");
+ if (autofacServiceScopeFactory == null)
+ {
+ throw new AbpException("Unable get type of Autofac.Extensions.DependencyInjection.AutofacServiceScopeFactory!");
+ }
+
+ // Issue #83: IServiceScopeFactory must be a singleton and scopes must be flat, not hierarchical.
+ builder
+ .RegisterType(autofacServiceScopeFactory)
+ .As()
+ .SingleInstance();
+
+ // Shims for keyed service compatibility.
+ builder.RegisterSource();
+ builder.ComponentRegistryBuilder.Registered += AddFromKeyedServiceParameterMiddleware;
+
+ Register(builder, services, lifetimeScopeTagForSingletons);
+ }
+
+ ///
+ /// Inspect each component registration, and determine whether or not we can avoid adding the
+ /// parameter to the resolve pipeline.
+ ///
+ private static void AddFromKeyedServiceParameterMiddleware(object? sender, ComponentRegisteredEventArgs e)
+ {
+ var needFromKeyedServiceParameter = false;
+
+ // We can optimise quite significantly in the case where we are using the reflection activator.
+ // In that state we can inspect the constructors ahead of time and determine whether the parameter will even need to be added.
+ if (e.ComponentRegistration.Activator is ReflectionActivator reflectionActivator)
+ {
+ var constructors = reflectionActivator.ConstructorFinder.FindConstructors(reflectionActivator.LimitType);
+
+ // Go through all the constructors; if any have a FromKeyedServices, then we must add our component middleware to
+ // the pipeline.
+ foreach (var constructor in constructors)
+ {
+ foreach (var constructorParameter in constructor.GetParameters())
+ {
+ if (constructorParameter.GetCustomAttribute() is not null)
+ {
+ // One or more of the constructors we will use to activate has a FromKeyedServicesAttribute,
+ // we must add our middleware.
+ needFromKeyedServiceParameter = true;
+ break;
+ }
+ }
+
+ if (needFromKeyedServiceParameter)
+ {
+ break;
+ }
+ }
+ }
+ else if (e.ComponentRegistration.Activator is DelegateActivator)
+ {
+ // For delegate activation there are very few paths that would let the FromKeyedServicesAttribute
+ // actually work, and none that MSDI supports directly.
+ // We're explicitly choosing here not to support [FromKeyedServices] on the Autofac-specific generic
+ // delegate resolve methods, to improve performance for the 99% case of other delegates that only
+ // receive an IComponentContext or an IServiceProvider.
+ needFromKeyedServiceParameter = false;
+ }
+ else if (e.ComponentRegistration.Activator is InstanceActivator)
+ {
+ // Instance activators don't use parameters.
+ needFromKeyedServiceParameter = false;
+ }
+ else
+ {
+ // Unknown activator, assume we need the parameter.
+ needFromKeyedServiceParameter = true;
+ }
+
+ e.ComponentRegistration.PipelineBuilding += (_, pipeline) =>
+ {
+ var keyedServiceMiddlewareType = typeof(AutofacServiceProvider).Assembly.GetType("Autofac.Extensions.DependencyInjection.KeyedServiceMiddleware");
+ var instanceWithFromKeyedServicesParameter = (IResolveMiddleware)keyedServiceMiddlewareType!.GetProperty("InstanceWithFromKeyedServicesParameter", BindingFlags.Public | BindingFlags.Static)!.GetValue(null, null)!;
+ var instanceWithoutFromKeyedServicesParameter = (IResolveMiddleware)keyedServiceMiddlewareType!.GetProperty("InstanceWithoutFromKeyedServicesParameter", BindingFlags.Public | BindingFlags.Static)!.GetValue(null, null)!;
+
+ if (needFromKeyedServiceParameter)
+ {
+ pipeline.Use(instanceWithFromKeyedServicesParameter, MiddlewareInsertionMode.StartOfPhase);
+ }
+ else
+ {
+ pipeline.Use(instanceWithoutFromKeyedServicesParameter, MiddlewareInsertionMode.StartOfPhase);
+ }
+ };
+ }
+
+ ///
+ /// Configures the exposed service type on a service registration.
+ ///
+ /// The activator data type.
+ /// The object registration style.
+ /// The registration being built.
+ /// The service descriptor with service type and key information.
+ ///
+ /// The , configured with the proper service type,
+ /// and available for additional configuration.
+ ///
+ private static IRegistrationBuilder