Browse Source

Merge pull request #18874 from abpframework/ConventionalControllers

Disable the `DynamicProxy` for `ConventionalControllers`.
pull/19028/head
Halil İbrahim Kalkan 3 years ago
committed by GitHub
parent
commit
3e753b3b43
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 4
      docs/en/API/Auto-API-Controllers.md
  2. 2
      docs/en/Integration-Services.md
  3. 4
      docs/zh-Hans/API/Auto-API-Controllers.md
  4. 13
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs
  5. 15
      framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/DynamicProxyIgnoreTypes.cs
  6. 8
      framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/ProxyHelper.cs
  7. 29
      framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs
  8. 21
      framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ConventionalController_Tests.cs
  9. 17
      framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/ConventionalAppService.cs

4
docs/en/API/Auto-API-Controllers.md

@ -12,9 +12,9 @@ Basic configuration is simple. Just configure `AbpAspNetCoreMvcOptions` and use
[DependsOn(BookStoreApplicationModule)] [DependsOn(BookStoreApplicationModule)]
public class BookStoreWebModule : AbpModule public class BookStoreWebModule : AbpModule
{ {
public override void ConfigureServices(ServiceConfigurationContext context) public override void PreConfigureServices(ServiceConfigurationContext context)
{ {
Configure<AbpAspNetCoreMvcOptions>(options => PreConfigure<AbpAspNetCoreMvcOptions>(options =>
{ {
options options
.ConventionalControllers .ConventionalControllers

2
docs/en/Integration-Services.md

@ -93,7 +93,7 @@ Configure<AbpAuditingOptions>(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: 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 ```csharp
Configure<AbpAspNetCoreMvcOptions>(options => PreConfigure<AbpAspNetCoreMvcOptions>(options =>
{ {
options.ConventionalControllers.Create( options.ConventionalControllers.Create(
typeof(MyApplicationModule).Assembly, typeof(MyApplicationModule).Assembly,

4
docs/zh-Hans/API/Auto-API-Controllers.md

@ -12,9 +12,9 @@ ABP可以按照惯例 **自动** 将你的应用程序服务配置为API控制
[DependsOn(BookStoreApplicationModule)] [DependsOn(BookStoreApplicationModule)]
public class BookStoreWebModule : AbpModule public class BookStoreWebModule : AbpModule
{ {
public override void ConfigureServices(ServiceConfigurationContext context) public override void PreConfigureServices(ServiceConfigurationContext context)
{ {
Configure<AbpAspNetCoreMvcOptions>(options => PreConfigure<AbpAspNetCoreMvcOptions>(options =>
{ {
options options
.ConventionalControllers .ConventionalControllers

13
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs

@ -212,6 +212,17 @@ public class AbpAspNetCoreMvcModule : AbpModule
context.Services.GetSingletonInstance<ApplicationPartManager>(), context.Services.GetSingletonInstance<ApplicationPartManager>(),
context.Services.GetSingletonInstance<IModuleContainer>() context.Services.GetSingletonInstance<IModuleContainer>()
); );
var preConfigureActions = context.Services.GetPreConfigureActions<AbpAspNetCoreMvcOptions>();
DynamicProxyIgnoreTypes.Add(preConfigureActions.Configure()
.ConventionalControllers
.ConventionalControllerSettings.SelectMany(x => x.ControllerTypes).ToArray());
Configure<AbpAspNetCoreMvcOptions>(options =>
{
preConfigureActions.Configure(options);
});
} }
public override void OnApplicationInitialization(ApplicationInitializationContext context) public override void OnApplicationInitialization(ApplicationInitializationContext context)
@ -247,7 +258,7 @@ public class AbpAspNetCoreMvcModule : AbpModule
.Distinct(); .Distinct();
AddToApplicationParts(partManager, controllerAssemblies); AddToApplicationParts(partManager, controllerAssemblies);
var additionalAssemblies = moduleContainer var additionalAssemblies = moduleContainer
.Modules .Modules
.SelectMany(m => m.GetAdditionalAssemblies()) .SelectMany(m => m.GetAdditionalAssemblies())

15
framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/DynamicProxyIgnoreTypes.cs

@ -17,10 +17,23 @@ public static class DynamicProxyIgnoreTypes
private static HashSet<Type> IgnoredTypes { get; } = new HashSet<Type>(); private static HashSet<Type> IgnoredTypes { get; } = new HashSet<Type>();
public static void Add<T>() public static void Add<T>()
{
Add(typeof(T));
}
public static void Add(Type type)
{
lock (IgnoredTypes)
{
IgnoredTypes.AddIfNotContains(type);
}
}
public static void Add(params Type[] types)
{ {
lock (IgnoredTypes) lock (IgnoredTypes)
{ {
IgnoredTypes.AddIfNotContains(typeof(T)); IgnoredTypes.AddIfNotContains(types);
} }
} }

8
framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/ProxyHelper.cs

@ -8,6 +8,14 @@ public static class ProxyHelper
{ {
private const string ProxyNamespace = "Castle.Proxies"; private const string ProxyNamespace = "Castle.Proxies";
/// <summary>
/// Checks if given object is a dynamic proxy.
/// </summary>
public static bool IsProxy(object obj)
{
return obj.GetType().Namespace == ProxyNamespace;
}
/// <summary> /// <summary>
/// Returns dynamic proxy target object if this is a proxied object, otherwise returns the given object. /// Returns dynamic proxy target object if this is a proxied object, otherwise returns the given object.
/// It supports Castle Dynamic Proxies. /// It supports Castle Dynamic Proxies.

29
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.MemoryDb;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Volo.Abp.TestApp; using Volo.Abp.TestApp;
using Volo.Abp.TestApp.Application;
using Volo.Abp.Threading; using Volo.Abp.Threading;
using Volo.Abp.Validation.Localization; using Volo.Abp.Validation.Localization;
using Volo.Abp.VirtualFileSystem; using Volo.Abp.VirtualFileSystem;
@ -44,6 +45,21 @@ public class AbpAspNetCoreMvcTestModule : AbpModule
typeof(AbpAspNetCoreMvcTestModule).Assembly typeof(AbpAspNetCoreMvcTestModule).Assembly
); );
}); });
context.Services.PreConfigure<AbpAspNetCoreMvcOptions>(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) public override void ConfigureServices(ServiceConfigurationContext context)
@ -79,19 +95,6 @@ public class AbpAspNetCoreMvcTestModule : AbpModule
}); });
}); });
Configure<AbpAspNetCoreMvcOptions>(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<AbpVirtualFileSystemOptions>(options => Configure<AbpVirtualFileSystemOptions>(options =>
{ {
options.FileSets.AddEmbedded<AbpAspNetCoreMvcTestModule>(); options.FileSets.AddEmbedded<AbpAspNetCoreMvcTestModule>();

21
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<PeopleAppService>();
ProxyHelper.IsProxy(peopleAppService).ShouldBeFalse();
// ConventionalAppService is not a conventional controller
var conventionalAppService = GetRequiredService<ConventionalAppService>();
ProxyHelper.IsProxy(conventionalAppService).ShouldBeTrue();
}
}

17
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;
}
}
Loading…
Cancel
Save