diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo.Abp.AspNetCore.Mvc.csproj b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo.Abp.AspNetCore.Mvc.csproj
index e190116b2f..e564dec738 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo.Abp.AspNetCore.Mvc.csproj
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo.Abp.AspNetCore.Mvc.csproj
@@ -21,6 +21,7 @@
+
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 e3cee4e72b..88a81fa1ec 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
@@ -10,14 +10,12 @@ using Microsoft.Extensions.Options;
using Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation;
using System;
using System.Collections.Generic;
-using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Reflection;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.AspNetCore.Mvc.DataAnnotations;
-using Microsoft.AspNetCore.Mvc.Razor;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure;
using Microsoft.AspNetCore.Routing;
@@ -34,6 +32,7 @@ using Volo.Abp.AspNetCore.VirtualFileSystem;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Http;
using Volo.Abp.DynamicProxy;
+using Volo.Abp.GlobalFeatures;
using Volo.Abp.Http.Modeling;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
@@ -46,7 +45,8 @@ namespace Volo.Abp.AspNetCore.Mvc
typeof(AbpLocalizationModule),
typeof(AbpApiVersioningAbstractionsModule),
typeof(AbpAspNetCoreMvcContractsModule),
- typeof(AbpUiModule)
+ typeof(AbpUiModule),
+ typeof(AbpGlobalFeaturesModule)
)]
public class AbpAspNetCoreMvcModule : AbpModule
{
@@ -168,7 +168,7 @@ namespace Volo.Abp.AspNetCore.Mvc
context.Services.Replace(ServiceDescriptor.Singleton());
context.Services.AddSingleton();
-
+
Configure(mvcOptions =>
{
mvcOptions.AddAbp(context.Services);
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/AbpServiceConvention.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/AbpServiceConvention.cs
index 0254a6022b..166640fe00 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/AbpServiceConvention.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/AbpServiceConvention.cs
@@ -10,6 +10,7 @@ using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.Extensions.Options;
using Volo.Abp.Application.Services;
using Volo.Abp.DependencyInjection;
+using Volo.Abp.GlobalFeatures;
using Volo.Abp.Http;
using Volo.Abp.Http.Modeling;
using Volo.Abp.Http.ProxyScripting.Generators;
@@ -142,18 +143,7 @@ namespace Volo.Abp.AspNetCore.Mvc.Conventions
if (controller.ApiExplorer.IsVisible == null)
{
- var controllerType = controller.ControllerType.AsType();
- var remoteServiceAtt = ReflectionHelper.GetSingleAttributeOrDefault(controllerType.GetTypeInfo());
- if (remoteServiceAtt != null)
- {
- controller.ApiExplorer.IsVisible =
- remoteServiceAtt.IsEnabledFor(controllerType) &&
- remoteServiceAtt.IsMetadataEnabledFor(controllerType);
- }
- else
- {
- controller.ApiExplorer.IsVisible = true;
- }
+ controller.ApiExplorer.IsVisible = IsVisibleRemoteService(controller.ControllerType);
}
foreach (var action in controller.Actions)
@@ -164,16 +154,18 @@ namespace Volo.Abp.AspNetCore.Mvc.Conventions
protected virtual void ConfigureApiExplorer(ActionModel action)
{
- if (action.ApiExplorer.IsVisible == null)
+ if (action.ApiExplorer.IsVisible != null)
{
- var remoteServiceAtt = ReflectionHelper.GetSingleAttributeOrDefault(action.ActionMethod);
- if (remoteServiceAtt != null)
- {
- action.ApiExplorer.IsVisible =
- remoteServiceAtt.IsEnabledFor(action.ActionMethod) &&
- remoteServiceAtt.IsMetadataEnabledFor(action.ActionMethod);
- }
+ return;
}
+
+ var visible = IsVisibleRemoteServiceMethod(action.ActionMethod);
+ if (visible == null)
+ {
+ return;
+ }
+
+ action.ApiExplorer.IsVisible = visible;
}
protected virtual void ConfigureSelector(ControllerModel controller, [CanBeNull] ConventionalControllerSetting configuration)
@@ -397,5 +389,45 @@ namespace Volo.Abp.AspNetCore.Mvc.Conventions
{
return typeof(IRemoteService).GetTypeInfo().IsAssignableFrom(controllerType);
}
+
+ protected virtual bool IsVisibleRemoteService(Type controllerType)
+ {
+ if (!IsGlobalFeatureEnabled(controllerType))
+ {
+ return false;
+ }
+
+ var attribute = ReflectionHelper.GetSingleAttributeOrDefault(controllerType);
+ if (attribute == null)
+ {
+ return true;
+ }
+
+ return attribute.IsEnabledFor(controllerType) &&
+ attribute.IsMetadataEnabledFor(controllerType);
+ }
+
+ protected virtual bool? IsVisibleRemoteServiceMethod(MethodInfo method)
+ {
+ var attribute = ReflectionHelper.GetSingleAttributeOrDefault(method);
+ if (attribute == null)
+ {
+ return null;
+ }
+
+ return attribute.IsEnabledFor(method) &&
+ attribute.IsMetadataEnabledFor(method);
+ }
+
+ protected virtual bool IsGlobalFeatureEnabled(Type controllerType)
+ {
+ var attribute = ReflectionHelper.GetSingleAttributeOrDefault(controllerType);
+ if (attribute == null)
+ {
+ return true;
+ }
+
+ return GlobalFeatureManager.Instance.IsEnabled(attribute.FeatureType);
+ }
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/GlobalFeatureManager.cs b/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/GlobalFeatureManager.cs
index 79badfe4e7..19a48a9da3 100644
--- a/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/GlobalFeatureManager.cs
+++ b/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/GlobalFeatureManager.cs
@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System;
+ using System.Collections.Generic;
using JetBrains.Annotations;
namespace Volo.Abp.GlobalFeatures
@@ -30,6 +31,11 @@ namespace Volo.Abp.GlobalFeatures
return IsEnabled(GlobalFeatureNameAttribute.GetName());
}
+ public virtual bool IsEnabled([NotNull] Type featureType)
+ {
+ return IsEnabled(GlobalFeatureNameAttribute.GetName(featureType));
+ }
+
public virtual bool IsEnabled(string featureName)
{
return EnabledFeatures.Contains(featureName);
diff --git a/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/GlobalFeatureNameAttribute.cs b/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/GlobalFeatureNameAttribute.cs
index 0563712899..2b987f6cb1 100644
--- a/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/GlobalFeatureNameAttribute.cs
+++ b/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/GlobalFeatureNameAttribute.cs
@@ -23,8 +23,10 @@ namespace Volo.Abp.GlobalFeatures
}
[NotNull]
- public static string GetName(Type type)
+ public static string GetName([NotNull] Type type)
{
+ Check.NotNull(type, nameof(type));
+
var attribute = type
.GetCustomAttributes()
.FirstOrDefault();
diff --git a/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/RequiresGlobalFeatureAttribute.cs b/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/RequiresGlobalFeatureAttribute.cs
new file mode 100644
index 0000000000..23ea10be81
--- /dev/null
+++ b/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/RequiresGlobalFeatureAttribute.cs
@@ -0,0 +1,15 @@
+using System;
+
+namespace Volo.Abp.GlobalFeatures
+{
+ [AttributeUsage(AttributeTargets.Class)]
+ public class RequiresGlobalFeatureAttribute : Attribute
+ {
+ public Type FeatureType { get; }
+
+ public RequiresGlobalFeatureAttribute(Type featureType)
+ {
+ FeatureType = featureType;
+ }
+ }
+}