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/AbpDesk/AbpDesk.Application.Contracts/AbpDesk/Tickets/ITicketAppService.cs b/src/AbpDesk/AbpDesk.Application.Contracts/AbpDesk/Tickets/ITicketAppService.cs index 6aca279236..81077e270e 100644 --- a/src/AbpDesk/AbpDesk.Application.Contracts/AbpDesk/Tickets/ITicketAppService.cs +++ b/src/AbpDesk/AbpDesk.Application.Contracts/AbpDesk/Tickets/ITicketAppService.cs @@ -8,5 +8,7 @@ namespace AbpDesk.Tickets public interface ITicketAppService : IApplicationService { Task> GetAll(GetAllTicketsInput input); + + ListResultDto GetAll2(GetAllTicketsInput input); } } diff --git a/src/AbpDesk/AbpDesk.Application/AbpDesk/Tickets/TicketAppService.cs b/src/AbpDesk/AbpDesk.Application/AbpDesk/Tickets/TicketAppService.cs index c68ddcc8a8..29af97062b 100644 --- a/src/AbpDesk/AbpDesk.Application/AbpDesk/Tickets/TicketAppService.cs +++ b/src/AbpDesk/AbpDesk.Application/AbpDesk/Tickets/TicketAppService.cs @@ -39,5 +39,23 @@ namespace AbpDesk.Tickets return new ListResultDto(tickets); } + + public ListResultDto GetAll2(GetAllTicketsInput input) + { + var tickets = _ticketRepository + .WhereIf( + !input.Filter.IsNullOrWhiteSpace(), + t => t.Title.Contains(input.Filter) || t.Body.Contains(input.Filter) + ) + .Select(t => new TicketDto + { + Id = t.Id, + Title = t.Title, + Body = t.Body + }) + .ToList(); + + return new ListResultDto(tickets); + } } } 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..bae546e095 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,34 +1,45 @@ using Castle.DynamicProxy; using Volo.Abp.DynamicProxy; +using Volo.Abp.Threading; +using Volo.ExtensionMethods; namespace Volo.Abp.Castle.DynamicProxy { - public class CastleAbpInterceptorAdapter : IInterceptor + public class CastleAbpInterceptorAdapter : IInterceptor + where TInterceptor : IAbpInterceptor { - private readonly IAbpInterceptor _abpInterceptor; + private readonly TInterceptor _abpInterceptor; - public CastleAbpInterceptorAdapter(IAbpInterceptor abpInterceptor) + public CastleAbpInterceptorAdapter(TInterceptor abpInterceptor) { _abpInterceptor = abpInterceptor; } public void Intercept(IInvocation invocation) { - _abpInterceptor.Intercept(new CastleAbpMethodInvocationAdapter(invocation)); + if (invocation.MethodInvocationTarget.IsAsync()) + { + InterceptAsyncMethod(invocation); + } + else + { + InterceptSyncMethod(invocation); + } } - } - - public class CastleAbpInterceptorAdapter : IInterceptor - where TInterceptor : IAbpInterceptor - { - private readonly TInterceptor _abpInterceptor; - public CastleAbpInterceptorAdapter(TInterceptor abpInterceptor) + private void InterceptAsyncMethod(IInvocation invocation) { - _abpInterceptor = abpInterceptor; + if (_abpInterceptor is IAbpAsyncInterceptor) + { + _abpInterceptor.As().InterceptAsync(new CastleAbpAsyncMethodInvocationAdapter(invocation)); + } + else + { + _abpInterceptor.Intercept(new CastleAbpMethodInvocationAdapter(invocation)); + } } - public void Intercept(IInvocation invocation) + private void InterceptSyncMethod(IInvocation invocation) { _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..c15aa48d8f 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,29 @@ -using System; -using System.Reflection; +using System.Threading.Tasks; using Castle.DynamicProxy; using Volo.Abp.DynamicProxy; +using Volo.Abp.Threading; 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(); + if (Invocation.Method.IsAsync()) + { + Invocation.Proceed(); + AsyncHelper.RunSync(() => (Task) Invocation.ReturnValue); + } + else + { + 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.TestBase/AbpIntegratedTest.cs b/src/Volo.Abp.TestBase/AbpIntegratedTest.cs index 3721ae1ba7..6d78afccd9 100644 --- a/src/Volo.Abp.TestBase/AbpIntegratedTest.cs +++ b/src/Volo.Abp.TestBase/AbpIntegratedTest.cs @@ -19,11 +19,12 @@ namespace Volo.Abp.TestBase BeforeAddApplication(services); - Application = services.AddApplication(); + Application = services.AddApplication(SetAbpApplicationCreationOptions); AfterAddApplication(services); - var serviceProvider = CreateServiceProvider(services); + MainServiceScope = CreateServiceProvider(services).CreateScope(); + var serviceProvider = MainServiceScope.ServiceProvider; Application.Initialize(serviceProvider); } @@ -38,6 +39,11 @@ namespace Volo.Abp.TestBase } + protected virtual void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) + { + + } + protected virtual void AfterAddApplication(IServiceCollection services) { @@ -45,8 +51,7 @@ namespace Volo.Abp.TestBase protected virtual IServiceProvider CreateServiceProvider(IServiceCollection services) { - MainServiceScope = services.BuildServiceProvider().CreateScope(); - return MainServiceScope.ServiceProvider; + return services.BuildServiceProvider(); } public void Dispose() 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/AbpDesk/AbpDesk.Application.Tests/AbpDesk/Tickets/TicketAppService_Tests.cs b/test/AbpDesk/AbpDesk.Application.Tests/AbpDesk/Tickets/TicketAppService_Tests.cs index ca56ac9b6a..06de028db7 100644 --- a/test/AbpDesk/AbpDesk.Application.Tests/AbpDesk/Tickets/TicketAppService_Tests.cs +++ b/test/AbpDesk/AbpDesk.Application.Tests/AbpDesk/Tickets/TicketAppService_Tests.cs @@ -38,5 +38,17 @@ namespace AbpDesk.Tickets result.Items.Count.ShouldBe(0); } + + [Fact] + public void GetAll2_Test() + { + //Act + + var result = _ticketAppService.GetAll2(new GetAllTicketsInput()); + + //Assert + + result.Items.Count.ShouldBe(1); + } } } 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..12d06b5c38 --- /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..83d5a50dda --- /dev/null +++ b/test/Volo.Abp.Autofac.Tests/Volo/Abp/Autofac/Interception/Autofac_Interception_Test.cs @@ -0,0 +1,44 @@ +using System; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Shouldly; +using Volo.Abp.Castle.DynamicProxy; +using Xunit; + +namespace Volo.Abp.Autofac.Interception +{ + public class Autofac_Interception_Test : CastleInterceptionTestBase + { + protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) + { + options.UseAutofac(); + } + + protected override IServiceProvider CreateServiceProvider(IServiceCollection services) + { + return services.BuildAutofacServiceProvider(); + } + + [Fact] + public async Task Should_Intercept_Async_Methods() + { + //Arrange + + var target = ServiceProvider.GetService(); + + //Act + + var result = await target.GetValueAsync(); + + //Assert + + result.ShouldBe(42); + target.Logs.Count.ShouldBe(5); + target.Logs[0].ShouldBe("SimpleInterceptor_BeforeInvocation"); + target.Logs[1].ShouldBe("EnterGetValueAsync"); + target.Logs[2].ShouldBe("MiddleGetValueAsync"); + target.Logs[3].ShouldBe("ExitGetValueAsync"); + target.Logs[4].ShouldBe("SimpleInterceptor_AfterInvocation"); + } + } +} 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..6bdfa007da --- /dev/null +++ b/test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/AbpCastleCoreTestModule.cs @@ -0,0 +1,29 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Castle.DynamicProxy; +using Volo.Abp.Modularity; + +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..497d1a3fc0 --- /dev/null +++ b/test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/DynamicProxy/CastleInterceptionTestBase.cs @@ -0,0 +1,34 @@ +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Shouldly; +using Volo.Abp.Modularity; +using Volo.Abp.TestBase; +using Xunit; + +namespace Volo.Abp.Castle.DynamicProxy +{ + //TODO: There is no Castle Dependency here.. We can move this base class directly to Volo.Abp.Tests + 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("SimpleInterceptor_BeforeInvocation"); + target.Logs[1].ShouldBe("ExecutingGetValue"); + target.Logs[2].ShouldBe("SimpleInterceptor_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..9acf2b1832 --- /dev/null +++ b/test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/DynamicProxy/SimpleInterceptionTargetClass.cs @@ -0,0 +1,28 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +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; + } + + public virtual async Task GetValueAsync() + { + Logs.Add("EnterGetValueAsync"); + await Task.Delay(1); + Logs.Add("MiddleGetValueAsync"); + await Task.Delay(1); + Logs.Add("ExitGetValueAsync"); + 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..e900d9a667 --- /dev/null +++ b/test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/DynamicProxy/SimpleInterceptor.cs @@ -0,0 +1,24 @@ +using System.Threading.Tasks; +using Volo.Abp.DynamicProxy; +using Volo.Abp.TestBase.Logging; +using Volo.DependencyInjection; + +namespace Volo.Abp.Castle.DynamicProxy +{ + public class SimpleInterceptor : IAbpInterceptor, /*IAbpAsyncInterceptor,*/ ITransientDependency + { + public void Intercept(IAbpMethodInvocation invocation) + { + (invocation.TargetObject as ICanLogOnObject)?.Logs?.Add("SimpleInterceptor_BeforeInvocation"); + invocation.Proceed(); + (invocation.TargetObject as ICanLogOnObject)?.Logs?.Add("SimpleInterceptor_AfterInvocation"); + } + + //public async Task InterceptAsync(IAbpAsyncMethodInvocation invocation) + //{ + // (invocation.TargetObject as ICanLogOnObject)?.Logs?.Add("SimpleInterceptor_BeforeInvocation"); + // await invocation.ProceedAsync(); + // (invocation.TargetObject as ICanLogOnObject)?.Logs?.Add("SimpleInterceptor_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 @@ - - - - - -