Browse Source

Created some helper extension methods for IServiceCollection. Also made AbpAppServiceConvention replaceable.

pull/96/head
Halil İbrahim Kalkan 9 years ago
parent
commit
95ec063037
  1. 51
      src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAppServiceConvention.cs
  2. 23
      src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAppServiceConventionWrapper.cs
  3. 2
      src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpMvcOptionsExtensions.cs
  4. 8
      src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/IAbpAppServiceConvention.cs
  5. 88
      src/Volo.Abp/Microsoft/Extensions/DependencyInjection/ServiceCollectionCommonExtensions.cs
  6. 1
      src/Volo.Abp/Properties/AssemblyInfo.cs

51
src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAppServiceConvention.cs

@ -7,28 +7,21 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApplicationModels; using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Microsoft.AspNetCore.Mvc.Internal; using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Volo.Abp.Application.Services; using Volo.Abp.Application.Services;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Http; using Volo.Abp.Http;
using Volo.Abp.Reflection; using Volo.Abp.Reflection;
namespace Volo.Abp.AspNetCore.Mvc namespace Volo.Abp.AspNetCore.Mvc
{ {
public class AbpAppServiceConvention : IApplicationModelConvention public class AbpAppServiceConvention : IAbpAppServiceConvention, ITransientDependency
{ {
private readonly Lazy<AbpAspNetCoreMvcOptions> _configuration; private readonly AbpAspNetCoreMvcOptions _options;
public AbpAppServiceConvention(IServiceCollection services) public AbpAppServiceConvention(IOptions<AbpAspNetCoreMvcOptions> options)
{ {
_configuration = new Lazy<AbpAspNetCoreMvcOptions>(() => _options = options.Value;
{
return services
.GetSingletonInstance<IAbpApplication>()
.ServiceProvider
.GetRequiredService<IOptions<AbpAspNetCoreMvcOptions>>()
.Value;
}, true);
} }
public void Apply(ApplicationModel application) public void Apply(ApplicationModel application)
@ -57,7 +50,7 @@ namespace Volo.Abp.AspNetCore.Mvc
} }
} }
private void ConfigureArea(ControllerModel controller, [CanBeNull] AbpControllerAssemblySetting configuration) protected virtual void ConfigureArea(ControllerModel controller, [CanBeNull] AbpControllerAssemblySetting configuration)
{ {
if (configuration == null) if (configuration == null)
{ {
@ -72,14 +65,14 @@ namespace Volo.Abp.AspNetCore.Mvc
controller.RouteValues["area"] = configuration.ModuleName; controller.RouteValues["area"] = configuration.ModuleName;
} }
private void ConfigureRemoteService(ControllerModel controller, [CanBeNull] AbpControllerAssemblySetting configuration) protected virtual void ConfigureRemoteService(ControllerModel controller, [CanBeNull] AbpControllerAssemblySetting configuration)
{ {
ConfigureApiExplorer(controller); ConfigureApiExplorer(controller);
ConfigureSelector(controller, configuration); ConfigureSelector(controller, configuration);
ConfigureParameters(controller); ConfigureParameters(controller);
} }
private void ConfigureParameters(ControllerModel controller) protected virtual void ConfigureParameters(ControllerModel controller)
{ {
foreach (var action in controller.Actions) foreach (var action in controller.Actions)
{ {
@ -101,9 +94,9 @@ namespace Volo.Abp.AspNetCore.Mvc
} }
} }
private bool CanUseFormBodyBinding(ActionModel action, ParameterModel parameter) protected virtual bool CanUseFormBodyBinding(ActionModel action, ParameterModel parameter)
{ {
if (_configuration.Value.FormBodyBindingIgnoredTypes.Any(t => t.IsAssignableFrom(parameter.ParameterInfo.ParameterType))) if (_options.FormBodyBindingIgnoredTypes.Any(t => t.IsAssignableFrom(parameter.ParameterInfo.ParameterType)))
{ {
return false; return false;
} }
@ -133,7 +126,7 @@ namespace Volo.Abp.AspNetCore.Mvc
return true; return true;
} }
private void ConfigureApiExplorer(ControllerModel controller) protected virtual void ConfigureApiExplorer(ControllerModel controller)
{ {
if (controller.ApiExplorer.GroupName.IsNullOrEmpty()) if (controller.ApiExplorer.GroupName.IsNullOrEmpty())
{ {
@ -162,7 +155,7 @@ namespace Volo.Abp.AspNetCore.Mvc
} }
} }
private void ConfigureApiExplorer(ActionModel action) protected virtual void ConfigureApiExplorer(ActionModel action)
{ {
if (action.ApiExplorer.IsVisible == null) if (action.ApiExplorer.IsVisible == null)
{ {
@ -176,7 +169,7 @@ namespace Volo.Abp.AspNetCore.Mvc
} }
} }
private void ConfigureSelector(ControllerModel controller, [CanBeNull] AbpControllerAssemblySetting configuration) protected virtual void ConfigureSelector(ControllerModel controller, [CanBeNull] AbpControllerAssemblySetting configuration)
{ {
RemoveEmptySelectors(controller.Selectors); RemoveEmptySelectors(controller.Selectors);
@ -193,7 +186,7 @@ namespace Volo.Abp.AspNetCore.Mvc
} }
} }
private void ConfigureSelector(string moduleName, string controllerName, ActionModel action, [CanBeNull] AbpControllerAssemblySetting configuration) protected virtual void ConfigureSelector(string moduleName, string controllerName, ActionModel action, [CanBeNull] AbpControllerAssemblySetting configuration)
{ {
RemoveEmptySelectors(action.Selectors); RemoveEmptySelectors(action.Selectors);
@ -207,7 +200,7 @@ namespace Volo.Abp.AspNetCore.Mvc
} }
} }
private void AddAbpServiceSelector(string moduleName, string controllerName, ActionModel action, [CanBeNull] AbpControllerAssemblySetting configuration) protected virtual void AddAbpServiceSelector(string moduleName, string controllerName, ActionModel action, [CanBeNull] AbpControllerAssemblySetting configuration)
{ {
var verb = configuration?.UseConventionalHttpVerbs == true var verb = configuration?.UseConventionalHttpVerbs == true
? HttpVerbHelper.GetConventionalVerbForMethodName(action.ActionName) ? HttpVerbHelper.GetConventionalVerbForMethodName(action.ActionName)
@ -222,7 +215,7 @@ namespace Volo.Abp.AspNetCore.Mvc
action.Selectors.Add(abpServiceSelectorModel); action.Selectors.Add(abpServiceSelectorModel);
} }
private static void NormalizeSelectorRoutes(string moduleName, string controllerName, ActionModel action) protected virtual void NormalizeSelectorRoutes(string moduleName, string controllerName, ActionModel action)
{ {
foreach (var selector in action.Selectors) foreach (var selector in action.Selectors)
{ {
@ -235,25 +228,25 @@ namespace Volo.Abp.AspNetCore.Mvc
} }
} }
private string GetModuleNameOrDefault(Type controllerType) protected virtual string GetModuleNameOrDefault(Type controllerType)
{ {
return GetControllerSettingOrNull(controllerType)?.ModuleName ?? return GetControllerSettingOrNull(controllerType)?.ModuleName ??
AbpControllerAssemblySetting.DefaultServiceModuleName; AbpControllerAssemblySetting.DefaultServiceModuleName;
} }
[CanBeNull] [CanBeNull]
private AbpControllerAssemblySetting GetControllerSettingOrNull(Type controllerType) protected virtual AbpControllerAssemblySetting GetControllerSettingOrNull(Type controllerType)
{ {
return _configuration.Value.ControllerAssemblySettings.GetSettingOrNull(controllerType); return _options.ControllerAssemblySettings.GetSettingOrNull(controllerType);
} }
private static AttributeRouteModel CreateAbpServiceAttributeRouteModel(string moduleName, string controllerName, ActionModel action, string verb) protected virtual AttributeRouteModel CreateAbpServiceAttributeRouteModel(string moduleName, string controllerName, ActionModel action, string verb)
{ {
var url = $"api/services/{moduleName}/{controllerName}/{action.ActionName}"; var url = $"api/services/{moduleName}/{controllerName}/{action.ActionName}";
return new AttributeRouteModel(new RouteAttribute(url)); return new AttributeRouteModel(new RouteAttribute(url));
} }
private static void RemoveEmptySelectors(IList<SelectorModel> selectors) protected virtual void RemoveEmptySelectors(IList<SelectorModel> selectors)
{ {
selectors selectors
.Where(IsEmptySelector) .Where(IsEmptySelector)
@ -261,7 +254,7 @@ namespace Volo.Abp.AspNetCore.Mvc
.ForEach(s => selectors.Remove(s)); .ForEach(s => selectors.Remove(s));
} }
private static bool IsEmptySelector(SelectorModel selector) protected virtual bool IsEmptySelector(SelectorModel selector)
{ {
return selector.AttributeRouteModel == null && selector.ActionConstraints.IsNullOrEmpty(); return selector.AttributeRouteModel == null && selector.ActionConstraints.IsNullOrEmpty();
} }

23
src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAppServiceConventionWrapper.cs

@ -0,0 +1,23 @@
using System;
using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AspNetCore.Mvc
{
[DisableConventionalRegistration]
public class AbpAppServiceConventionWrapper : IApplicationModelConvention
{
private readonly Lazy<IAbpAppServiceConvention> _convention;
public AbpAppServiceConventionWrapper(IServiceCollection services)
{
_convention = services.GetRequiredServiceLazy<IAbpAppServiceConvention>();
}
public void Apply(ApplicationModel application)
{
_convention.Value.Apply(application);
}
}
}

2
src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpMvcOptionsExtensions.cs

@ -14,7 +14,7 @@ namespace Volo.Abp.AspNetCore.Mvc
private static void AddConventions(MvcOptions options, IServiceCollection services) private static void AddConventions(MvcOptions options, IServiceCollection services)
{ {
options.Conventions.Add(new AbpAppServiceConvention(services)); options.Conventions.Add(new AbpAppServiceConventionWrapper(services));
} }
private static void AddFilters(MvcOptions options) private static void AddFilters(MvcOptions options)

8
src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/IAbpAppServiceConvention.cs

@ -0,0 +1,8 @@
using Microsoft.AspNetCore.Mvc.ApplicationModels;
namespace Volo.Abp.AspNetCore.Mvc
{
public interface IAbpAppServiceConvention : IApplicationModelConvention
{
}
}

88
src/Volo.Abp/Microsoft/Extensions/DependencyInjection/ServiceCollectionCommonExtensions.cs

@ -69,5 +69,91 @@ namespace Microsoft.Extensions.DependencyInjection
builderAction?.Invoke(builder); builderAction?.Invoke(builder);
return serviceProviderFactory.CreateServiceProvider(builder); return serviceProviderFactory.CreateServiceProvider(builder);
} }
}
/// <summary>
/// Resolves a dependency using given <see cref="IServiceCollection"/>.
/// This method should be used only after dependency injection registration phase completed.
/// </summary>
internal static T GetService<T>(this IServiceCollection services)
{
return services
.GetSingletonInstance<IAbpApplication>()
.ServiceProvider
.GetService<T>();
}
/// <summary>
/// Resolves a dependency using given <see cref="IServiceCollection"/>.
/// This method should be used only after dependency injection registration phase completed.
/// </summary>
internal static object GetService(this IServiceCollection services, Type type)
{
return services
.GetSingletonInstance<IAbpApplication>()
.ServiceProvider
.GetService(type);
}
/// <summary>
/// Resolves a dependency using given <see cref="IServiceCollection"/>.
/// Throws exception if service is not registered.
/// This method should be used only after dependency injection registration phase completed.
/// </summary>
internal static T GetRequiredService<T>(this IServiceCollection services)
{
return services
.GetSingletonInstance<IAbpApplication>()
.ServiceProvider
.GetRequiredService<T>();
}
/// <summary>
/// Resolves a dependency using given <see cref="IServiceCollection"/>.
/// Throws exception if service is not registered.
/// This method should be used only after dependency injection registration phase completed.
/// </summary>
internal static object GetRequiredService(this IServiceCollection services, Type type)
{
return services
.GetSingletonInstance<IAbpApplication>()
.ServiceProvider
.GetRequiredService(type);
}
/// <summary>
/// Returns a <see cref="Lazy{T}"/> to resolve a service from given <see cref="IServiceCollection"/>
/// once dependency injection registration phase completed.
/// </summary>
internal static Lazy<T> GetServiceLazy<T>(this IServiceCollection services)
{
return new Lazy<T>(services.GetService<T>, true);
}
/// <summary>
/// Returns a <see cref="Lazy{T}"/> to resolve a service from given <see cref="IServiceCollection"/>
/// once dependency injection registration phase completed.
/// </summary>
internal static Lazy<object> GetServiceLazy(this IServiceCollection services, Type type)
{
return new Lazy<object>(() => services.GetService(type), true);
}
/// <summary>
/// Returns a <see cref="Lazy{T}"/> to resolve a service from given <see cref="IServiceCollection"/>
/// once dependency injection registration phase completed.
/// </summary>
internal static Lazy<T> GetRequiredServiceLazy<T>(this IServiceCollection services)
{
return new Lazy<T>(services.GetRequiredService<T>, true);
}
/// <summary>
/// Returns a <see cref="Lazy{T}"/> to resolve a service from given <see cref="IServiceCollection"/>
/// once dependency injection registration phase completed.
/// </summary>
internal static Lazy<object> GetRequiredServiceLazy(this IServiceCollection services, Type type)
{
return new Lazy<object>(() => services.GetRequiredService(type), true);
}
}
} }

1
src/Volo.Abp/Properties/AssemblyInfo.cs

@ -11,6 +11,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: InternalsVisibleTo("Volo.Abp.Tests")] [assembly: InternalsVisibleTo("Volo.Abp.Tests")]
[assembly: InternalsVisibleTo("Volo.Abp.AspNetCore.Mvc")]
// Setting ComVisible to false makes the types in this assembly not visible // Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from // to COM components. If you need to access a type in this assembly from

Loading…
Cancel
Save