diff --git a/docs/en/API/Auto-API-Controllers.md b/docs/en/API/Auto-API-Controllers.md index 0ffbc644a8..a81da00b98 100644 --- a/docs/en/API/Auto-API-Controllers.md +++ b/docs/en/API/Auto-API-Controllers.md @@ -12,9 +12,9 @@ Basic configuration is simple. Just configure `AbpAspNetCoreMvcOptions` and use [DependsOn(BookStoreApplicationModule)] public class BookStoreWebModule : AbpModule { - public override void ConfigureServices(ServiceConfigurationContext context) + public override void PreConfigureServices(ServiceConfigurationContext context) { - Configure(options => + PreConfigure(options => { options .ConventionalControllers diff --git a/docs/en/Integration-Services.md b/docs/en/Integration-Services.md index 98e3e593e5..6c31fb69bf 100644 --- a/docs/en/Integration-Services.md +++ b/docs/en/Integration-Services.md @@ -93,7 +93,7 @@ Configure(options => You can filter integration services (or non-integration services) while creating [Auto API Controllers](API/Auto-API-Controllers.md), using the `ApplicationServiceTypes` option of the `ConventionalControllerSetting` by configuring the `AbpAspNetCoreMvcOptions` as shown below: ```csharp -Configure(options => +PreConfigure(options => { options.ConventionalControllers.Create( typeof(MyApplicationModule).Assembly, diff --git a/docs/zh-Hans/API/Auto-API-Controllers.md b/docs/zh-Hans/API/Auto-API-Controllers.md index c3f5d44d71..e284d05c3d 100644 --- a/docs/zh-Hans/API/Auto-API-Controllers.md +++ b/docs/zh-Hans/API/Auto-API-Controllers.md @@ -12,9 +12,9 @@ ABP可以按照惯例 **自动** 将你的应用程序服务配置为API控制 [DependsOn(BookStoreApplicationModule)] public class BookStoreWebModule : AbpModule { - public override void ConfigureServices(ServiceConfigurationContext context) + public override void PreConfigureServices(ServiceConfigurationContext context) { - Configure(options => + PreConfigure(options => { options .ConventionalControllers diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs index a2f2c1c989..7b68fca32d 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs @@ -215,6 +215,17 @@ public class AbpAspNetCoreMvcModule : AbpModule context.Services.GetSingletonInstance(), context.Services.GetSingletonInstance() ); + + var preConfigureActions = context.Services.GetPreConfigureActions(); + + DynamicProxyIgnoreTypes.Add(preConfigureActions.Configure() + .ConventionalControllers + .ConventionalControllerSettings.SelectMany(x => x.ControllerTypes).ToArray()); + + Configure(options => + { + preConfigureActions.Configure(options); + }); } public override void OnApplicationInitialization(ApplicationInitializationContext context) diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/DynamicProxyIgnoreTypes.cs b/framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/DynamicProxyIgnoreTypes.cs index a24d888b43..d14f64a55b 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/DynamicProxyIgnoreTypes.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/DynamicProxyIgnoreTypes.cs @@ -17,10 +17,23 @@ public static class DynamicProxyIgnoreTypes private static HashSet IgnoredTypes { get; } = new HashSet(); public static void Add() + { + Add(typeof(T)); + } + + public static void Add(Type type) + { + lock (IgnoredTypes) + { + IgnoredTypes.AddIfNotContains(type); + } + } + + public static void Add(params Type[] types) { lock (IgnoredTypes) { - IgnoredTypes.AddIfNotContains(typeof(T)); + IgnoredTypes.AddIfNotContains(types); } } diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/ProxyHelper.cs b/framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/ProxyHelper.cs index 5b4f6c6349..203794a6d9 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/ProxyHelper.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/ProxyHelper.cs @@ -8,6 +8,14 @@ public static class ProxyHelper { private const string ProxyNamespace = "Castle.Proxies"; + /// + /// Checks if given object is a dynamic proxy. + /// + public static bool IsProxy(object obj) + { + return obj.GetType().Namespace == ProxyNamespace; + } + /// /// Returns dynamic proxy target object if this is a proxied object, otherwise returns the given object. /// It supports Castle Dynamic Proxies. diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs index 6051ae6520..3f9c605f64 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs @@ -19,6 +19,7 @@ using Volo.Abp.Localization; using Volo.Abp.MemoryDb; using Volo.Abp.Modularity; using Volo.Abp.TestApp; +using Volo.Abp.TestApp.Application; using Volo.Abp.Threading; using Volo.Abp.Validation.Localization; using Volo.Abp.VirtualFileSystem; @@ -44,6 +45,21 @@ public class AbpAspNetCoreMvcTestModule : AbpModule typeof(AbpAspNetCoreMvcTestModule).Assembly ); }); + + context.Services.PreConfigure(options => + { + options.ConventionalControllers.Create(typeof(TestAppModule).Assembly, opts => + { + opts.UrlActionNameNormalizer = urlActionNameNormalizerContext => + string.Equals(urlActionNameNormalizerContext.ActionNameInUrl, "phone", StringComparison.OrdinalIgnoreCase) + ? "phones" + : urlActionNameNormalizerContext.ActionNameInUrl; + + opts.TypePredicate = type => type != typeof(ConventionalAppService); + }); + + options.ExposeIntegrationServices = true; + }); } public override void ConfigureServices(ServiceConfigurationContext context) @@ -79,19 +95,6 @@ public class AbpAspNetCoreMvcTestModule : AbpModule }); }); - Configure(options => - { - options.ConventionalControllers.Create(typeof(TestAppModule).Assembly, opts => - { - opts.UrlActionNameNormalizer = urlActionNameNormalizerContext => - string.Equals(urlActionNameNormalizerContext.ActionNameInUrl, "phone", StringComparison.OrdinalIgnoreCase) - ? "phones" - : urlActionNameNormalizerContext.ActionNameInUrl; - }); - - options.ExposeIntegrationServices = true; - }); - Configure(options => { options.FileSets.AddEmbedded(); diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ConventionalController_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ConventionalController_Tests.cs new file mode 100644 index 0000000000..41602ff1e8 --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ConventionalController_Tests.cs @@ -0,0 +1,21 @@ +using Shouldly; +using Volo.Abp.DynamicProxy; +using Volo.Abp.TestApp.Application; +using Xunit; + +namespace Volo.Abp.AspNetCore.Mvc; + +public class ConventionalController_Tests : AspNetCoreMvcTestBase +{ + [Fact] + public void Conventional_Controller_Should_Disable_DynamicProxy() + { + // PeopleAppService is a conventional controller + var peopleAppService = GetRequiredService(); + ProxyHelper.IsProxy(peopleAppService).ShouldBeFalse(); + + // ConventionalAppService is not a conventional controller + var conventionalAppService = GetRequiredService(); + ProxyHelper.IsProxy(conventionalAppService).ShouldBeTrue(); + } +} diff --git a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/ConventionalAppService.cs b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/ConventionalAppService.cs new file mode 100644 index 0000000000..4d38d8989b --- /dev/null +++ b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/ConventionalAppService.cs @@ -0,0 +1,17 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; +using Volo.Abp.Application.Services; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Uow; + +namespace Volo.Abp.TestApp.Application; + +public class ConventionalAppService : IApplicationService, ITransientDependency +{ + [Authorize] + [UnitOfWork] + public virtual Task GetAsync() + { + return Task.CompletedTask; + } +}