From 684051efa4e9d5c02722a4d44c5cc086feae5a04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Fri, 5 May 2017 20:56:56 +0300 Subject: [PATCH] Worked on async interceptors. --- Volo.Abp.sln | 14 +++++ .../AbpRegistrationBuilderExtensions.cs | 63 ++++++++++++------- .../AutofacRegistration.cs | 44 ++++++------- .../CastleAbpAsyncMethodInvocationAdapter.cs | 21 +++++++ .../CastleAbpInterceptorAdapter.cs | 26 +++----- .../CastleAbpMethodInvocationAdapter.cs | 27 ++------ .../CastleAbpMethodInvocationAdapterBase.cs | 31 +++++++++ ...ctionConventionalRegistrationExtensions.cs | 5 ++ .../Abp/DynamicProxy/IAbpAsyncInterceptor.cs | 9 +++ .../DynamicProxy/IAbpAsyncMethodInvocation.cs | 9 +++ .../Abp/DynamicProxy/IAbpMethodInvocation.cs | 15 +---- .../DynamicProxy/IAbpMethodInvocationCore.cs | 18 ++++++ .../Volo/Abp/Threading/InternalAsyncHelper.cs | 2 +- .../Volo/Abp/Uow/UnitOfWorkInterceptor.cs | 23 ++++--- test/AbpTestBase/AbpTestBase.csproj | 2 + .../Abp/TestBase/Logging/ICanLogOnObject.cs | 9 +++ ...o.Abp.AspNetCore.MultiTenancy.Tests.csproj | 6 -- .../Volo.Abp.AspNetCore.Tests.csproj | 6 -- .../Volo.Abp.Autofac.Tests.csproj | 25 ++++++++ .../Volo/Abp/Autofac/AutofacTestModule.cs | 16 +++++ .../Interception/Autofac_Interception_Test.cs | 9 +++ .../Volo.Abp.Castle.Core.Tests.csproj | 24 +++++++ .../Abp/Castle/AbpCastleCoreTestModule.cs | 30 +++++++++ .../CastleInterceptionTestBase.cs | 32 ++++++++++ .../SimpleInterceptionTargetClass.cs | 17 +++++ .../Castle/DynamicProxy/SimpleInterceptor.cs | 16 +++++ .../Volo.Abp.MultiTenancy.Tests.csproj | 6 -- test/Volo.Abp.Tests/Volo.Abp.Tests.csproj | 6 -- 28 files changed, 377 insertions(+), 134 deletions(-) create mode 100644 src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpAsyncMethodInvocationAdapter.cs create mode 100644 src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpMethodInvocationAdapterBase.cs create mode 100644 src/Volo.Abp/Volo/Abp/DynamicProxy/IAbpAsyncInterceptor.cs create mode 100644 src/Volo.Abp/Volo/Abp/DynamicProxy/IAbpAsyncMethodInvocation.cs create mode 100644 src/Volo.Abp/Volo/Abp/DynamicProxy/IAbpMethodInvocationCore.cs create mode 100644 test/AbpTestBase/Volo/Abp/TestBase/Logging/ICanLogOnObject.cs create mode 100644 test/Volo.Abp.Autofac.Tests/Volo.Abp.Autofac.Tests.csproj create mode 100644 test/Volo.Abp.Autofac.Tests/Volo/Abp/Autofac/AutofacTestModule.cs create mode 100644 test/Volo.Abp.Autofac.Tests/Volo/Abp/Autofac/Interception/Autofac_Interception_Test.cs create mode 100644 test/Volo.Abp.Castle.Core.Tests/Volo.Abp.Castle.Core.Tests.csproj create mode 100644 test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/AbpCastleCoreTestModule.cs create mode 100644 test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/DynamicProxy/CastleInterceptionTestBase.cs create mode 100644 test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/DynamicProxy/SimpleInterceptionTargetClass.cs create mode 100644 test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/DynamicProxy/SimpleInterceptor.cs diff --git a/Volo.Abp.sln b/Volo.Abp.sln index adab6a5b0c..ce61195bed 100644 --- a/Volo.Abp.sln +++ b/Volo.Abp.sln @@ -110,6 +110,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Autofac", "src\Vol EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Castle.Core", "src\Volo.Abp.Castle.Core\Volo.Abp.Castle.Core.csproj", "{053F7446-0545-482E-9F29-9C96B926966C}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Autofac.Tests", "test\Volo.Abp.Autofac.Tests\Volo.Abp.Autofac.Tests.csproj", "{D8BE64D2-BD83-40F5-9783-D7FDDF668C45}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Castle.Core.Tests", "test\Volo.Abp.Castle.Core.Tests\Volo.Abp.Castle.Core.Tests.csproj", "{CE12E5C2-7B3E-4637-B6A3-274BB5C3DE16}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -264,6 +268,14 @@ Global {053F7446-0545-482E-9F29-9C96B926966C}.Debug|Any CPU.Build.0 = Debug|Any CPU {053F7446-0545-482E-9F29-9C96B926966C}.Release|Any CPU.ActiveCfg = Release|Any CPU {053F7446-0545-482E-9F29-9C96B926966C}.Release|Any CPU.Build.0 = Release|Any CPU + {D8BE64D2-BD83-40F5-9783-D7FDDF668C45}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D8BE64D2-BD83-40F5-9783-D7FDDF668C45}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D8BE64D2-BD83-40F5-9783-D7FDDF668C45}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D8BE64D2-BD83-40F5-9783-D7FDDF668C45}.Release|Any CPU.Build.0 = Release|Any CPU + {CE12E5C2-7B3E-4637-B6A3-274BB5C3DE16}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CE12E5C2-7B3E-4637-B6A3-274BB5C3DE16}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CE12E5C2-7B3E-4637-B6A3-274BB5C3DE16}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CE12E5C2-7B3E-4637-B6A3-274BB5C3DE16}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -315,5 +327,7 @@ Global {00B240B6-EC44-461A-9578-EF4F1BE9C688} = {1895A5C9-50D4-4568-9A3A-14657E615A5E} {CECE1288-B5A1-4A6B-BEE0-331861F94983} = {4C753F64-0C93-4D65-96C2-A40893AFC1E8} {053F7446-0545-482E-9F29-9C96B926966C} = {4C753F64-0C93-4D65-96C2-A40893AFC1E8} + {D8BE64D2-BD83-40F5-9783-D7FDDF668C45} = {37087D1B-3693-4E96-983D-A69F210BDE53} + {CE12E5C2-7B3E-4637-B6A3-274BB5C3DE16} = {37087D1B-3693-4E96-983D-A69F210BDE53} EndGlobalSection EndGlobal diff --git a/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs b/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs index 80bc8fe279..69379461d9 100644 --- a/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs +++ b/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs @@ -1,42 +1,59 @@ -using System.Linq; +using System; +using System.Linq; using System.Reflection; using Autofac.Core; using Autofac.Extras.DynamicProxy; -using Volo.Abp.Application.Services; +using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Castle.DynamicProxy; -using Volo.Abp.Uow; namespace Autofac.Builder { public static class AbpRegistrationBuilderExtensions { - public static IRegistrationBuilder ApplyAbpConcepts( - this IRegistrationBuilder registrationBuilder) + public static IRegistrationBuilder ConfigureAbpConventions( + this IRegistrationBuilder registrationBuilder, + IServiceCollection services) where TConcreteReflectionActivatorData : ConcreteReflectionActivatorData { - //TODO: Refactor to an extensible way! - var serviceType = registrationBuilder.RegistrationData.Services.OfType().FirstOrDefault()?.ServiceType; + if (serviceType == null) + { + return registrationBuilder; + } - if (serviceType != null) + var serviceRegistredArgs = new OnServiceRegistredArgs(serviceType); + + foreach (var registrationAction in services.GetServiceRegistrationActionList()) { - if (typeof(IApplicationService).IsAssignableFrom(serviceType)) - { - if (serviceType.GetTypeInfo().IsInterface) - { - registrationBuilder = registrationBuilder.EnableInterfaceInterceptors(); - } - else - { - registrationBuilder = registrationBuilder.EnableClassInterceptors(); - } - - registrationBuilder.InterceptedBy( - typeof(CastleAbpInterceptorAdapter<>).MakeGenericType(typeof(UnitOfWorkInterceptor)) - ); - } + registrationAction.Invoke(serviceRegistredArgs); } + if (serviceRegistredArgs.Interceptors.Any()) + { + registrationBuilder = registrationBuilder.AddInterceptors(serviceRegistredArgs.Interceptors.ToArray()); + } + + return registrationBuilder; + } + + private static IRegistrationBuilder AddInterceptors( + this IRegistrationBuilder registrationBuilder, + Type[] interceptors + ) + where TConcreteReflectionActivatorData : ConcreteReflectionActivatorData + { + var serviceType = registrationBuilder.RegistrationData.Services.OfType().FirstOrDefault()?.ServiceType; + + registrationBuilder = serviceType.GetTypeInfo().IsInterface + ? registrationBuilder.EnableInterfaceInterceptors() + : registrationBuilder.EnableClassInterceptors(); + + foreach (var interceptor in interceptors) + { + registrationBuilder.InterceptedBy( + typeof(CastleAbpInterceptorAdapter<>).MakeGenericType(interceptor) + ); + } return registrationBuilder; } } diff --git a/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacRegistration.cs b/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacRegistration.cs index 1d5e688dda..1ac2967705 100644 --- a/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacRegistration.cs +++ b/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacRegistration.cs @@ -44,17 +44,17 @@ namespace Autofac.Extensions.DependencyInjection /// /// The into which the registrations should be made. /// - /// + /// /// The set of service descriptors to register in the container. /// public static void Populate( this ContainerBuilder builder, - IEnumerable descriptors) + IServiceCollection services) { builder.RegisterType().As(); builder.RegisterType().As(); - Register(builder, descriptors); + Register(builder, services); } /// @@ -94,43 +94,43 @@ namespace Autofac.Extensions.DependencyInjection /// /// The into which the registrations should be made. /// - /// + /// /// The set of service descriptors to register in the container. /// private static void Register( ContainerBuilder builder, - IEnumerable descriptors) + IServiceCollection services) { - foreach (var descriptor in descriptors) + foreach (var service in services) { - if (descriptor.ImplementationType != null) + if (service.ImplementationType != null) { // Test if the an open generic type is being registered - var serviceTypeInfo = descriptor.ServiceType.GetTypeInfo(); + var serviceTypeInfo = service.ServiceType.GetTypeInfo(); if (serviceTypeInfo.IsGenericTypeDefinition) { builder - .RegisterGeneric(descriptor.ImplementationType) - .As(descriptor.ServiceType) - .ConfigureLifecycle(descriptor.Lifetime); + .RegisterGeneric(service.ImplementationType) + .As(service.ServiceType) + .ConfigureLifecycle(service.Lifetime); } else { builder - .RegisterType(descriptor.ImplementationType) - .As(descriptor.ServiceType) - .ConfigureLifecycle(descriptor.Lifetime) - .ApplyAbpConcepts(); + .RegisterType(service.ImplementationType) + .As(service.ServiceType) + .ConfigureLifecycle(service.Lifetime) + .ConfigureAbpConventions(services); } } - else if (descriptor.ImplementationFactory != null) + else if (service.ImplementationFactory != null) { - var registration = RegistrationBuilder.ForDelegate(descriptor.ServiceType, (context, parameters) => + var registration = RegistrationBuilder.ForDelegate(service.ServiceType, (context, parameters) => { var serviceProvider = context.Resolve(); - return descriptor.ImplementationFactory(serviceProvider); + return service.ImplementationFactory(serviceProvider); }) - .ConfigureLifecycle(descriptor.Lifetime) + .ConfigureLifecycle(service.Lifetime) .CreateRegistration(); builder.RegisterComponent(registration); @@ -138,9 +138,9 @@ namespace Autofac.Extensions.DependencyInjection else { builder - .RegisterInstance(descriptor.ImplementationInstance) - .As(descriptor.ServiceType) - .ConfigureLifecycle(descriptor.Lifetime); + .RegisterInstance(service.ImplementationInstance) + .As(service.ServiceType) + .ConfigureLifecycle(service.Lifetime); } } } diff --git a/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpAsyncMethodInvocationAdapter.cs b/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpAsyncMethodInvocationAdapter.cs new file mode 100644 index 0000000000..fca81bc053 --- /dev/null +++ b/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpAsyncMethodInvocationAdapter.cs @@ -0,0 +1,21 @@ +using System.Threading.Tasks; +using Castle.DynamicProxy; +using Volo.Abp.DynamicProxy; + +namespace Volo.Abp.Castle.DynamicProxy +{ + public class CastleAbpAsyncMethodInvocationAdapter : CastleAbpMethodInvocationAdapterBase, IAbpAsyncMethodInvocation + { + public CastleAbpAsyncMethodInvocationAdapter(IInvocation invocation) + : base(invocation) + { + + } + + public Task ProceedAsync() + { + Invocation.Proceed(); + return (Task)Invocation.ReturnValue; + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpInterceptorAdapter.cs b/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpInterceptorAdapter.cs index 5d27f8e025..adf674ac7e 100644 --- a/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpInterceptorAdapter.cs +++ b/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpInterceptorAdapter.cs @@ -1,23 +1,10 @@ using Castle.DynamicProxy; using Volo.Abp.DynamicProxy; +using Volo.Abp.Threading; +using Volo.ExtensionMethods; namespace Volo.Abp.Castle.DynamicProxy { - public class CastleAbpInterceptorAdapter : IInterceptor - { - private readonly IAbpInterceptor _abpInterceptor; - - public CastleAbpInterceptorAdapter(IAbpInterceptor abpInterceptor) - { - _abpInterceptor = abpInterceptor; - } - - public void Intercept(IInvocation invocation) - { - _abpInterceptor.Intercept(new CastleAbpMethodInvocationAdapter(invocation)); - } - } - public class CastleAbpInterceptorAdapter : IInterceptor where TInterceptor : IAbpInterceptor { @@ -30,7 +17,14 @@ namespace Volo.Abp.Castle.DynamicProxy public void Intercept(IInvocation invocation) { - _abpInterceptor.Intercept(new CastleAbpMethodInvocationAdapter(invocation)); + if (invocation.MethodInvocationTarget.IsAsync() && _abpInterceptor is IAbpAsyncInterceptor) + { + _abpInterceptor.As().InterceptAsync(new CastleAbpAsyncMethodInvocationAdapter(invocation)); + } + else + { + _abpInterceptor.Intercept(new CastleAbpMethodInvocationAdapter(invocation)); + } } } } diff --git a/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpMethodInvocationAdapter.cs b/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpMethodInvocationAdapter.cs index ee9c0dba69..4a2dcf5cfe 100644 --- a/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpMethodInvocationAdapter.cs +++ b/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpMethodInvocationAdapter.cs @@ -1,36 +1,19 @@ -using System; -using System.Reflection; -using Castle.DynamicProxy; +using Castle.DynamicProxy; using Volo.Abp.DynamicProxy; namespace Volo.Abp.Castle.DynamicProxy { - public class CastleAbpMethodInvocationAdapter : IAbpMethodInvocation + public class CastleAbpMethodInvocationAdapter : CastleAbpMethodInvocationAdapterBase, IAbpMethodInvocation { - public object[] Arguments => _invocation.Arguments; - - public Type[] GenericArguments => _invocation.GenericArguments; - - public object TargetObject => _invocation.InvocationTarget; - - public MethodInfo Method => _invocation.MethodInvocationTarget; - - public object ReturnValue - { - get => _invocation.ReturnValue; - set => _invocation.ReturnValue = value; - } - - private readonly IInvocation _invocation; - public CastleAbpMethodInvocationAdapter(IInvocation invocation) + : base(invocation) { - _invocation = invocation; + } public void Proceed() { - _invocation.Proceed(); + Invocation.Proceed(); } } } \ No newline at end of file diff --git a/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpMethodInvocationAdapterBase.cs b/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpMethodInvocationAdapterBase.cs new file mode 100644 index 0000000000..788960b206 --- /dev/null +++ b/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpMethodInvocationAdapterBase.cs @@ -0,0 +1,31 @@ +using System; +using System.Reflection; +using Castle.DynamicProxy; +using Volo.Abp.DynamicProxy; + +namespace Volo.Abp.Castle.DynamicProxy +{ + public abstract class CastleAbpMethodInvocationAdapterBase : IAbpMethodInvocationCore + { + public object[] Arguments => Invocation.Arguments; + + public Type[] GenericArguments => Invocation.GenericArguments; + + public object TargetObject => Invocation.InvocationTarget; + + public MethodInfo Method => Invocation.MethodInvocationTarget; + + public object ReturnValue + { + get => Invocation.ReturnValue; + set => Invocation.ReturnValue = value; + } + + protected IInvocation Invocation { get; } + + protected CastleAbpMethodInvocationAdapterBase(IInvocation invocation) + { + Invocation = invocation; + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp/Microsoft/Extensions/DependencyInjection/ServiceCollectionConventionalRegistrationExtensions.cs b/src/Volo.Abp/Microsoft/Extensions/DependencyInjection/ServiceCollectionConventionalRegistrationExtensions.cs index c06bed4236..3954ba5946 100644 --- a/src/Volo.Abp/Microsoft/Extensions/DependencyInjection/ServiceCollectionConventionalRegistrationExtensions.cs +++ b/src/Volo.Abp/Microsoft/Extensions/DependencyInjection/ServiceCollectionConventionalRegistrationExtensions.cs @@ -55,6 +55,11 @@ namespace Microsoft.Extensions.DependencyInjection return services; } + public static IServiceCollection AddType(this IServiceCollection services) + { + return services.AddType(typeof(TType)); + } + public static IServiceCollection AddType(this IServiceCollection services, Type type) { foreach (var registrar in services.GetConventionalRegistrars()) diff --git a/src/Volo.Abp/Volo/Abp/DynamicProxy/IAbpAsyncInterceptor.cs b/src/Volo.Abp/Volo/Abp/DynamicProxy/IAbpAsyncInterceptor.cs new file mode 100644 index 0000000000..dd5cadbc4c --- /dev/null +++ b/src/Volo.Abp/Volo/Abp/DynamicProxy/IAbpAsyncInterceptor.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.DynamicProxy +{ + public interface IAbpAsyncInterceptor + { + Task InterceptAsync(IAbpAsyncMethodInvocation invocation); + } +} \ No newline at end of file diff --git a/src/Volo.Abp/Volo/Abp/DynamicProxy/IAbpAsyncMethodInvocation.cs b/src/Volo.Abp/Volo/Abp/DynamicProxy/IAbpAsyncMethodInvocation.cs new file mode 100644 index 0000000000..560ad95821 --- /dev/null +++ b/src/Volo.Abp/Volo/Abp/DynamicProxy/IAbpAsyncMethodInvocation.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.DynamicProxy +{ + public interface IAbpAsyncMethodInvocation: IAbpMethodInvocationCore + { + Task ProceedAsync(); + } +} \ No newline at end of file diff --git a/src/Volo.Abp/Volo/Abp/DynamicProxy/IAbpMethodInvocation.cs b/src/Volo.Abp/Volo/Abp/DynamicProxy/IAbpMethodInvocation.cs index 41a842ee6c..a7c22fe895 100644 --- a/src/Volo.Abp/Volo/Abp/DynamicProxy/IAbpMethodInvocation.cs +++ b/src/Volo.Abp/Volo/Abp/DynamicProxy/IAbpMethodInvocation.cs @@ -1,20 +1,7 @@ -using System; -using System.Reflection; - namespace Volo.Abp.DynamicProxy { - public interface IAbpMethodInvocation + public interface IAbpMethodInvocation: IAbpMethodInvocationCore { - object[] Arguments { get; } - - Type[] GenericArguments { get; } - - object TargetObject { get; } - - MethodInfo Method { get; } - - object ReturnValue { get; set; } - void Proceed(); } } \ No newline at end of file diff --git a/src/Volo.Abp/Volo/Abp/DynamicProxy/IAbpMethodInvocationCore.cs b/src/Volo.Abp/Volo/Abp/DynamicProxy/IAbpMethodInvocationCore.cs new file mode 100644 index 0000000000..bf5f34371f --- /dev/null +++ b/src/Volo.Abp/Volo/Abp/DynamicProxy/IAbpMethodInvocationCore.cs @@ -0,0 +1,18 @@ +using System; +using System.Reflection; + +namespace Volo.Abp.DynamicProxy +{ + public interface IAbpMethodInvocationCore + { + object[] Arguments { get; } + + Type[] GenericArguments { get; } + + object TargetObject { get; } + + MethodInfo Method { get; } + + object ReturnValue { get; set; } + } +} \ No newline at end of file diff --git a/src/Volo.Abp/Volo/Abp/Threading/InternalAsyncHelper.cs b/src/Volo.Abp/Volo/Abp/Threading/InternalAsyncHelper.cs index 0dabef6e86..38b8cd2f0e 100644 --- a/src/Volo.Abp/Volo/Abp/Threading/InternalAsyncHelper.cs +++ b/src/Volo.Abp/Volo/Abp/Threading/InternalAsyncHelper.cs @@ -4,7 +4,7 @@ using System.Threading.Tasks; namespace Volo.Abp.Threading { - internal static class InternalAsyncHelper + public static class InternalAsyncHelper //TODO: Rename since it's not internal anymore! { public static async Task AwaitTaskWithFinally(Task actualReturnValue, Action finalAction) { diff --git a/src/Volo.Abp/Volo/Abp/Uow/UnitOfWorkInterceptor.cs b/src/Volo.Abp/Volo/Abp/Uow/UnitOfWorkInterceptor.cs index 46875cc933..16a15ba585 100644 --- a/src/Volo.Abp/Volo/Abp/Uow/UnitOfWorkInterceptor.cs +++ b/src/Volo.Abp/Volo/Abp/Uow/UnitOfWorkInterceptor.cs @@ -5,7 +5,7 @@ using Volo.DependencyInjection; namespace Volo.Abp.Uow { - public class UnitOfWorkInterceptor : IAbpInterceptor, ITransientDependency + public class UnitOfWorkInterceptor : IAbpInterceptor, IAbpAsyncInterceptor, ITransientDependency { private readonly IUnitOfWorkManager _unitOfWorkManager; @@ -13,31 +13,30 @@ namespace Volo.Abp.Uow { _unitOfWorkManager = unitOfWorkManager; } - - + public void Intercept(IAbpMethodInvocation invocation) { //TODO: Check UOW attribute and other conditions! - if (invocation.Method.IsAsync()) - { - PerformAsyncUow(invocation); - } - else + using (var uow = _unitOfWorkManager.Begin()) { - PerformSyncUow(invocation); + invocation.Proceed(); + uow.Complete(); } } - private void PerformSyncUow(IAbpMethodInvocation invocation) + public async Task InterceptAsync(IAbpAsyncMethodInvocation invocation) { + //TODO: Check UOW attribute and other conditions! + using (var uow = _unitOfWorkManager.Begin()) { - invocation.Proceed(); - uow.Complete(); + await invocation.ProceedAsync(); + await uow.CompleteAsync(); } } + private void PerformAsyncUow(IAbpMethodInvocation invocation) { var uow = _unitOfWorkManager.Begin(); diff --git a/test/AbpTestBase/AbpTestBase.csproj b/test/AbpTestBase/AbpTestBase.csproj index 493c3b162c..60ae154661 100644 --- a/test/AbpTestBase/AbpTestBase.csproj +++ b/test/AbpTestBase/AbpTestBase.csproj @@ -16,10 +16,12 @@ + + diff --git a/test/AbpTestBase/Volo/Abp/TestBase/Logging/ICanLogOnObject.cs b/test/AbpTestBase/Volo/Abp/TestBase/Logging/ICanLogOnObject.cs new file mode 100644 index 0000000000..1583b70950 --- /dev/null +++ b/test/AbpTestBase/Volo/Abp/TestBase/Logging/ICanLogOnObject.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace Volo.Abp.TestBase.Logging +{ + public interface ICanLogOnObject + { + List Logs { get; } + } +} \ No newline at end of file diff --git a/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo.Abp.AspNetCore.MultiTenancy.Tests.csproj b/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo.Abp.AspNetCore.MultiTenancy.Tests.csproj index 7c71a75ff1..353526ccf1 100644 --- a/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo.Abp.AspNetCore.MultiTenancy.Tests.csproj +++ b/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo.Abp.AspNetCore.MultiTenancy.Tests.csproj @@ -18,12 +18,6 @@ - - - - - - diff --git a/test/Volo.Abp.AspNetCore.Tests/Volo.Abp.AspNetCore.Tests.csproj b/test/Volo.Abp.AspNetCore.Tests/Volo.Abp.AspNetCore.Tests.csproj index f2c0550075..20462299f6 100644 --- a/test/Volo.Abp.AspNetCore.Tests/Volo.Abp.AspNetCore.Tests.csproj +++ b/test/Volo.Abp.AspNetCore.Tests/Volo.Abp.AspNetCore.Tests.csproj @@ -17,10 +17,4 @@ - - - - - - diff --git a/test/Volo.Abp.Autofac.Tests/Volo.Abp.Autofac.Tests.csproj b/test/Volo.Abp.Autofac.Tests/Volo.Abp.Autofac.Tests.csproj new file mode 100644 index 0000000000..cb305a458d --- /dev/null +++ b/test/Volo.Abp.Autofac.Tests/Volo.Abp.Autofac.Tests.csproj @@ -0,0 +1,25 @@ + + + + netcoreapp1.1 + Volo.Abp.Autofac.Tests + Volo.Abp.Autofac.Tests + true + 1.1.1 + false + false + false + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/Volo.Abp.Autofac.Tests/Volo/Abp/Autofac/AutofacTestModule.cs b/test/Volo.Abp.Autofac.Tests/Volo/Abp/Autofac/AutofacTestModule.cs new file mode 100644 index 0000000000..9ae98678d4 --- /dev/null +++ b/test/Volo.Abp.Autofac.Tests/Volo/Abp/Autofac/AutofacTestModule.cs @@ -0,0 +1,16 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Castle; +using Volo.Abp.Castle.DynamicProxy; +using Volo.Abp.Modularity; + +namespace Volo.Abp.Autofac +{ + [DependsOn(typeof(AbpAutofacModule), typeof(AbpCastleCoreTestModule))] + public class AutofacTestModule : AbpModule + { + public override void ConfigureServices(IServiceCollection services) + { + services.AddAssemblyOf(); + } + } +} \ No newline at end of file diff --git a/test/Volo.Abp.Autofac.Tests/Volo/Abp/Autofac/Interception/Autofac_Interception_Test.cs b/test/Volo.Abp.Autofac.Tests/Volo/Abp/Autofac/Interception/Autofac_Interception_Test.cs new file mode 100644 index 0000000000..cc2dcc1c4d --- /dev/null +++ b/test/Volo.Abp.Autofac.Tests/Volo/Abp/Autofac/Interception/Autofac_Interception_Test.cs @@ -0,0 +1,9 @@ +using Volo.Abp.Castle.DynamicProxy; + +namespace Volo.Abp.Autofac.Interception +{ + public class Autofac_Interception_Test : CastleInterceptionTestBase + { + + } +} diff --git a/test/Volo.Abp.Castle.Core.Tests/Volo.Abp.Castle.Core.Tests.csproj b/test/Volo.Abp.Castle.Core.Tests/Volo.Abp.Castle.Core.Tests.csproj new file mode 100644 index 0000000000..4fc2425f21 --- /dev/null +++ b/test/Volo.Abp.Castle.Core.Tests/Volo.Abp.Castle.Core.Tests.csproj @@ -0,0 +1,24 @@ + + + + netcoreapp1.1 + Volo.Abp.Castle.Core.Tests + Volo.Abp.Castle.Core.Tests + true + 1.1.1 + false + false + false + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/AbpCastleCoreTestModule.cs b/test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/AbpCastleCoreTestModule.cs new file mode 100644 index 0000000000..09b984e26d --- /dev/null +++ b/test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/AbpCastleCoreTestModule.cs @@ -0,0 +1,30 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Castle.DynamicProxy; +using Volo.Abp.Modularity; +using Volo.Abp.Uow; + +namespace Volo.Abp.Castle +{ + [DependsOn(typeof(AbpCastleCoreModule))] + public class AbpCastleCoreTestModule : AbpModule + { + public override void PreConfigureServices(IServiceCollection services) + { + services.OnServiceRegistred(RegisterTestInterceptors); + } + + public override void ConfigureServices(IServiceCollection services) + { + services.AddAssemblyOf(); + } + + private static void RegisterTestInterceptors(IOnServiceRegistredArgs registration) + { + //TODO: Create an attribute to add interceptors! + if (typeof(SimpleInterceptionTargetClass) == registration.ImplementationType) + { + registration.Interceptors.Add(); + } + } + } +} diff --git a/test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/DynamicProxy/CastleInterceptionTestBase.cs b/test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/DynamicProxy/CastleInterceptionTestBase.cs new file mode 100644 index 0000000000..67a997fed2 --- /dev/null +++ b/test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/DynamicProxy/CastleInterceptionTestBase.cs @@ -0,0 +1,32 @@ +using Microsoft.Extensions.DependencyInjection; +using Shouldly; +using Volo.Abp.Modularity; +using Volo.Abp.TestBase; +using Xunit; + +namespace Volo.Abp.Castle.DynamicProxy +{ + public abstract class CastleInterceptionTestBase : AbpIntegratedTest + where TStartupModule : IAbpModule + { + [Fact] + public void Should_Intercept_Sync_Methods() + { + //Arrange + + var target = ServiceProvider.GetService(); + + //Act + + var result = target.GetValue(); + + //Assert + + result.ShouldBe(42); + target.Logs.Count.ShouldBe(3); + target.Logs[0].ShouldBe("BeforeInvocation"); + target.Logs[1].ShouldBe("ExecutingGetValue"); + target.Logs[2].ShouldBe("AfterInvocation"); + } + } +} \ No newline at end of file diff --git a/test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/DynamicProxy/SimpleInterceptionTargetClass.cs b/test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/DynamicProxy/SimpleInterceptionTargetClass.cs new file mode 100644 index 0000000000..b9acd96d95 --- /dev/null +++ b/test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/DynamicProxy/SimpleInterceptionTargetClass.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; +using Volo.Abp.TestBase.Logging; +using Volo.DependencyInjection; + +namespace Volo.Abp.Castle.DynamicProxy +{ + public class SimpleInterceptionTargetClass : ITransientDependency, ICanLogOnObject + { + public List Logs { get; } = new List(); + + public virtual int GetValue() + { + Logs.Add("ExecutingGetValue"); + return 42; + } + } +} \ No newline at end of file diff --git a/test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/DynamicProxy/SimpleInterceptor.cs b/test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/DynamicProxy/SimpleInterceptor.cs new file mode 100644 index 0000000000..c7ac128415 --- /dev/null +++ b/test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/DynamicProxy/SimpleInterceptor.cs @@ -0,0 +1,16 @@ +using Volo.Abp.DynamicProxy; +using Volo.Abp.TestBase.Logging; +using Volo.DependencyInjection; + +namespace Volo.Abp.Castle.DynamicProxy +{ + public class SimpleInterceptor : IAbpInterceptor, ITransientDependency + { + public void Intercept(IAbpMethodInvocation invocation) + { + (invocation.TargetObject as ICanLogOnObject)?.Logs?.Add("BeforeInvocation"); + invocation.Proceed(); + (invocation.TargetObject as ICanLogOnObject)?.Logs?.Add("AfterInvocation"); + } + } +} \ No newline at end of file diff --git a/test/Volo.Abp.MultiTenancy.Tests/Volo.Abp.MultiTenancy.Tests.csproj b/test/Volo.Abp.MultiTenancy.Tests/Volo.Abp.MultiTenancy.Tests.csproj index 8b9983d0b1..a6ba500b67 100644 --- a/test/Volo.Abp.MultiTenancy.Tests/Volo.Abp.MultiTenancy.Tests.csproj +++ b/test/Volo.Abp.MultiTenancy.Tests/Volo.Abp.MultiTenancy.Tests.csproj @@ -17,12 +17,6 @@ - - - - - - diff --git a/test/Volo.Abp.Tests/Volo.Abp.Tests.csproj b/test/Volo.Abp.Tests/Volo.Abp.Tests.csproj index 8cedfb06e0..3ade5e7435 100644 --- a/test/Volo.Abp.Tests/Volo.Abp.Tests.csproj +++ b/test/Volo.Abp.Tests/Volo.Abp.Tests.csproj @@ -21,12 +21,6 @@ - - - - - -