Browse Source

Merge pull request #14051 from abpframework/integration-services-improvements

Integration services improvements
pull/14059/head
Halil İbrahim Kalkan 4 years ago
committed by GitHub
parent
commit
b9a29f685a
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 9
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditActionFilter.cs
  2. 31
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/ConventionalControllerSetting.cs
  3. 2
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/ConventionalRouteBuilder.cs
  4. 3
      framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingInterceptorRegistrar.cs
  5. 22
      framework/src/Volo.Abp.Core/Volo/Abp/ApplicationServiceTypes.cs
  6. 25
      framework/src/Volo.Abp.Core/Volo/Abp/IntegrationServiceAttribute.cs
  7. 51
      framework/src/Volo.Abp.Http.Client/Microsoft/Extensions/DependencyInjection/ServiceCollectionHttpClientProxyExtensions.cs
  8. 48
      framework/test/Volo.Abp.Core.Tests/Volo/Abp/IntegrationServiceAttribute_Tests.cs

9
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditActionFilter.cs

@ -93,10 +93,11 @@ public class AbpAuditActionFilter : IAsyncActionFilter, ITransientDependency
ActionDescriptor actionDescriptor)
{
if (!abpAuditingOptions.IsEnabledForIntegrationServices &&
actionDescriptor
.AsControllerActionDescriptor()
.ControllerTypeInfo
.IsDefined(typeof(IntegrationServiceAttribute), true))
IntegrationServiceAttribute.IsDefinedOrInherited(
actionDescriptor
.AsControllerActionDescriptor()
.ControllerTypeInfo)
)
{
return false;
}

31
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/ConventionalControllerSetting.cs

@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Microsoft.AspNetCore.Mvc.Versioning;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Reflection;
using Volo.Abp.Reflection;
@ -16,7 +17,7 @@ public class ConventionalControllerSetting
public Assembly Assembly { get; }
[NotNull]
public HashSet<Type> ControllerTypes { get; } //TODO: Internal?
internal HashSet<Type> ControllerTypes { get; }
/// <summary>
/// Set true to use the old style URL path style.
@ -47,6 +48,11 @@ public class ConventionalControllerSetting
[CanBeNull]
public Func<Type, bool> TypePredicate { get; set; }
/// <summary>
/// Default value: All.
/// </summary>
public ApplicationServiceTypes ApplicationServiceTypes { get; set; } = ApplicationServiceTypes.All;
[CanBeNull]
public Action<ControllerModel> ControllerModelConfigurer { get; set; }
@ -77,6 +83,7 @@ public class ConventionalControllerSetting
{
var types = Assembly.GetTypes()
.Where(IsRemoteService)
.Where(IsPreferredApplicationServiceType)
.WhereIf(TypePredicate != null, TypePredicate);
foreach (var type in types)
@ -84,6 +91,11 @@ public class ConventionalControllerSetting
ControllerTypes.Add(type);
}
}
public IReadOnlyList<Type> GetControllerTypes()
{
return ControllerTypes.ToImmutableList();
}
private static bool IsRemoteService(Type type)
{
@ -105,4 +117,19 @@ public class ConventionalControllerSetting
return false;
}
}
private bool IsPreferredApplicationServiceType(Type type)
{
if (ApplicationServiceTypes == ApplicationServiceTypes.ApplicationServices)
{
return !IntegrationServiceAttribute.IsDefinedOrInherited(type);
}
if (ApplicationServiceTypes == ApplicationServiceTypes.IntegrationServices)
{
return IntegrationServiceAttribute.IsDefinedOrInherited(type);
}
return true;
}
}

2
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/ConventionalRouteBuilder.cs

@ -73,7 +73,7 @@ public class ConventionalRouteBuilder : IConventionalRouteBuilder, ITransientDep
protected virtual string GetApiRoutePrefix(ActionModel actionModel, ConventionalControllerSetting configuration)
{
if (actionModel.Controller.ControllerType.IsDefined(typeof(IntegrationServiceAttribute), true))
if (IntegrationServiceAttribute.IsDefinedOrInherited(actionModel.Controller.ControllerType))
{
return AbpAspNetCoreConsts.DefaultIntegrationServiceApiPrefix;
}

3
framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingInterceptorRegistrar.cs

@ -52,7 +52,8 @@ public static class AuditingInterceptorRegistrar
if (typeof(IAuditingEnabled).IsAssignableFrom(type))
{
if (ignoreIntegrationServiceAttribute || !type.IsDefined(typeof(IntegrationServiceAttribute), true))
if (ignoreIntegrationServiceAttribute ||
!IntegrationServiceAttribute.IsDefinedOrInherited(type))
{
return true;
}

22
framework/src/Volo.Abp.Core/Volo/Abp/ApplicationServiceTypes.cs

@ -0,0 +1,22 @@
using System;
namespace Volo.Abp;
[Flags]
public enum ApplicationServiceTypes : byte
{
/// <summary>
/// Only application services without <see cref="IntegrationServiceAttribute"/>.
/// </summary>
ApplicationServices = 1,
/// <summary>
/// Application services with <see cref="IntegrationServiceAttribute"/>.
/// </summary>
IntegrationServices = 2,
/// <summary>
/// All application services.
/// </summary>
All = ApplicationServices | IntegrationServices
}

25
framework/src/Volo.Abp.Core/Volo/Abp/IntegrationServiceAttribute.cs

@ -2,8 +2,29 @@
namespace Volo.Abp;
[AttributeUsage(AttributeTargets.Class)]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)]
public class IntegrationServiceAttribute : Attribute
{
public static bool IsDefinedOrInherited<T>()
{
return IsDefinedOrInherited(typeof(T));
}
public static bool IsDefinedOrInherited(Type type)
{
if (type.IsDefined(typeof(IntegrationServiceAttribute), true))
{
return true;
}
foreach (var @interface in type.GetInterfaces())
{
if (@interface.IsDefined(typeof(IntegrationServiceAttribute), true))
{
return true;
}
}
return false;
}
}

51
framework/src/Volo.Abp.Http.Client/Microsoft/Extensions/DependencyInjection/ServiceCollectionHttpClientProxyExtensions.cs

@ -28,14 +28,22 @@ public static class ServiceCollectionHttpClientProxyExtensions
/// The name of the remote service configuration to be used by the Static HTTP Client proxies.
/// See <see cref="AbpRemoteServiceOptions"/>.
/// </param>
/// <param name="applicationServiceTypes">
/// Can be set to filter the application service types to be registered.
/// Default value: All.
/// </param>
public static IServiceCollection AddStaticHttpClientProxies(
[NotNull] this IServiceCollection services,
[NotNull] Assembly assembly,
[NotNull] string remoteServiceConfigurationName = RemoteServiceConfigurationDictionary.DefaultName)
[NotNull] string remoteServiceConfigurationName = RemoteServiceConfigurationDictionary.DefaultName,
ApplicationServiceTypes applicationServiceTypes = ApplicationServiceTypes.All)
{
Check.NotNull(services, nameof(assembly));
var serviceTypes = assembly.GetTypes().Where(IsSuitableForClientProxying).ToArray();
var serviceTypes = assembly
.GetTypes()
.Where(x => IsSuitableForClientProxying(x, applicationServiceTypes))
.ToArray();
foreach (var serviceType in serviceTypes)
{
@ -64,15 +72,23 @@ public static class ServiceCollectionHttpClientProxyExtensions
/// <param name="asDefaultServices">
/// True, to register the HTTP client proxy as the default implementation for the services.
/// </param>
/// <param name="applicationServiceTypes">
/// Can be set to filter the application service types to be registered.
/// Default value: All.
/// </param>
public static IServiceCollection AddHttpClientProxies(
[NotNull] this IServiceCollection services,
[NotNull] Assembly assembly,
[NotNull] string remoteServiceConfigurationName = RemoteServiceConfigurationDictionary.DefaultName,
bool asDefaultServices = true)
bool asDefaultServices = true,
ApplicationServiceTypes applicationServiceTypes = ApplicationServiceTypes.All)
{
Check.NotNull(services, nameof(assembly));
var serviceTypes = assembly.GetTypes().Where(IsSuitableForClientProxying).ToArray();
var serviceTypes = assembly
.GetTypes()
.Where(x => IsSuitableForClientProxying(x, applicationServiceTypes))
.ToArray();
foreach (var serviceType in serviceTypes)
{
@ -228,13 +244,28 @@ public static class ServiceCollectionHttpClientProxyExtensions
/// </summary>
/// <param name="type">Type to check</param>
/// <returns>True, if the type is suitable for proxying. Otherwise false.</returns>
private static bool IsSuitableForClientProxying(Type type)
private static bool IsSuitableForClientProxying(
Type type,
ApplicationServiceTypes applicationServiceTypes)
{
//TODO: Add option to change type filter
if (!type.IsInterface ||
!type.IsPublic ||
type.IsGenericType ||
!typeof(IRemoteService).IsAssignableFrom(type))
{
return false;
}
if (applicationServiceTypes == ApplicationServiceTypes.ApplicationServices)
{
return !IntegrationServiceAttribute.IsDefinedOrInherited(type);
}
if (applicationServiceTypes == ApplicationServiceTypes.IntegrationServices)
{
return IntegrationServiceAttribute.IsDefinedOrInherited(type);
}
return type.IsInterface
&& type.IsPublic
&& !type.IsGenericType
&& typeof(IRemoteService).IsAssignableFrom(type);
return true;
}
}

48
framework/test/Volo.Abp.Core.Tests/Volo/Abp/IntegrationServiceAttribute_Tests.cs

@ -0,0 +1,48 @@
using Shouldly;
using Xunit;
namespace Volo.Abp;
public class IntegrationServiceAttribute_Tests
{
[Fact]
public static void IsDefinedOrInherited()
{
// True cases
IntegrationServiceAttribute
.IsDefinedOrInherited<IMyIntegrationService1>()
.ShouldBeTrue();
IntegrationServiceAttribute
.IsDefinedOrInherited<MyIntegrationService1>()
.ShouldBeTrue();
IntegrationServiceAttribute
.IsDefinedOrInherited<MyIntegrationService2>()
.ShouldBeTrue();
// False cases
IntegrationServiceAttribute
.IsDefinedOrInherited<IMyIntegrationService2>()
.ShouldBeFalse();
IntegrationServiceAttribute
.IsDefinedOrInherited<MyApplicationService>()
.ShouldBeFalse();
}
[IntegrationService]
private interface IMyIntegrationService1 { }
private class MyIntegrationService1 : IMyIntegrationService1 { }
private interface IMyIntegrationService2 { }
[IntegrationService]
private class MyIntegrationService2 : IMyIntegrationService2 { }
private interface IMyApplicationService { }
private class MyApplicationService : IMyApplicationService { }
}
Loading…
Cancel
Save