Make "application services as controllers" working.

pull/96/head
Halil İbrahim Kalkan 8 years ago
parent 8172382883
commit 38519a001a

@ -0,0 +1,45 @@
using System;
using System.Reflection;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Volo.Abp.Application.Services;
using Volo.Abp.Http;
using Volo.Abp.Reflection;
namespace Volo.Abp.AspNetCore.Mvc
{
/// <summary>
/// Used to add application services as controller.
/// </summary>
public class AbpAppServiceControllerFeatureProvider : ControllerFeatureProvider
{
private readonly IAbpApplication _application;
public AbpAppServiceControllerFeatureProvider(IAbpApplication application)
{
_application = application;
}
protected override bool IsController(TypeInfo typeInfo)
{
var type = typeInfo.AsType();
if (!typeof(IApplicationService).IsAssignableFrom(type) ||
!typeInfo.IsPublic || typeInfo.IsAbstract || typeInfo.IsGenericType)
{
return false;
}
var remoteServiceAttr = ReflectionHelper.GetSingleAttributeOrDefault<RemoteServiceAttribute>(typeInfo);
if (remoteServiceAttr != null && !remoteServiceAttr.IsEnabledFor(type))
{
return false;
}
var configuration = _application.ServiceProvider.GetRequiredService<IOptions<AbpAspNetCoreMvcOptions>>().Value.ControllerAssemblySettings.GetSettingOrNull(type);
return configuration != null && configuration.TypePredicate(type);
}
}
}

@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.AspNetCore.Mvc.Razor;
using Microsoft.Extensions.DependencyInjection;
@ -9,6 +11,10 @@ using Volo.Abp.AspNetCore.EmbeddedFiles;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Modularity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc.ViewComponents;
using Microsoft.Extensions.DependencyInjection.Extensions;
namespace Volo.Abp.AspNetCore.Mvc
{
@ -35,6 +41,26 @@ namespace Volo.Abp.AspNetCore.Mvc
)
)
);
}
public override void PostConfigureServices(IServiceCollection services)
{
//TODO: Consider to use services.AddMvc() and move this to ConfigureServices method!
services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.TryAddSingleton<IActionContextAccessor, ActionContextAccessor>();
//Use DI to create controllers
services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());
//Use DI to create view components
services.Replace(ServiceDescriptor.Singleton<IViewComponentActivator, ServiceBasedViewComponentActivator>());
//Add feature providers
var partManager = services.GetSingletonInstance<ApplicationPartManager>();
var application = services.GetSingletonInstance<IAbpApplication>();
partManager.FeatureProviders.Add(new AbpAppServiceControllerFeatureProvider(application));
services.Configure<MvcOptions>(mvcOptions =>
{
@ -55,11 +81,40 @@ namespace Volo.Abp.AspNetCore.Mvc
return;
}
var moduleContainer = context.ServiceProvider.GetRequiredService<IModuleContainer>();
//Plugin modules
var moduleAssemblies = context
.ServiceProvider
.GetRequiredService<IModuleContainer>()
.Modules
.Where(m => m.IsLoadedAsPlugIn)
.Select(m => m.Type.Assembly)
.Distinct();
foreach (var module in moduleContainer.Modules.Where(m => m.IsLoadedAsPlugIn))
AddToApplicationParts(partManager, moduleAssemblies);
//Controllers for application services
var controllerAssemblies = context
.ServiceProvider
.GetRequiredService<IOptions<AbpAspNetCoreMvcOptions>>()
.Value
.ControllerAssemblySettings
.Select(s => s.Assembly)
.Distinct();
AddToApplicationParts(partManager, controllerAssemblies);
}
private static void AddToApplicationParts(ApplicationPartManager partManager, IEnumerable<Assembly> moduleAssemblies)
{
foreach (var moduleAssembly in moduleAssemblies)
{
partManager.ApplicationParts.Add(new AssemblyPart(module.Type.GetTypeInfo().Assembly));
if (partManager.ApplicationParts.OfType<AssemblyPart>().Any(p => p.Assembly == moduleAssembly))
{
continue;
}
partManager.ApplicationParts.Add(new AssemblyPart(moduleAssembly));
}
}
}

@ -13,6 +13,7 @@ namespace Volo.Abp.AspNetCore.Mvc
public AbpAspNetCoreMvcOptions()
{
ControllerAssemblySettings = new ControllerAssemblySettingList();
FormBodyBindingIgnoredTypes = new List<Type>
{
typeof(IFormFile)

@ -25,9 +25,12 @@ namespace Volo.Abp
ServiceProvider = serviceProvider;
ServiceProvider
.GetRequiredService<IModuleManager>()
.InitializeModules(new ApplicationInitializationContext(ServiceProvider));
using (var scope = ServiceProvider.CreateScope())
{
ServiceProvider
.GetRequiredService<IModuleManager>()
.InitializeModules(new ApplicationInitializationContext(scope.ServiceProvider));
}
}
}
}

@ -36,9 +36,13 @@ namespace Volo.Abp
{
ServiceScope = Services.BuildServiceProviderFromFactory().CreateScope();
ServiceProvider = ServiceScope.ServiceProvider;
ServiceProvider
.GetRequiredService<IModuleManager>()
.InitializeModules(new ApplicationInitializationContext(ServiceProvider));
using (var scope = ServiceProvider.CreateScope())
{
ServiceProvider
.GetRequiredService<IModuleManager>()
.InitializeModules(new ApplicationInitializationContext(scope.ServiceProvider));
}
}
public override void Dispose()

@ -4,6 +4,7 @@ using System.Linq.Dynamic.Core;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.ObjectMapping;
namespace Volo.Abp.Application.Services
{

@ -19,6 +19,7 @@
<ProjectReference Include="..\..\src\Volo.Abp.AspNetCore.Mvc\Volo.Abp.AspNetCore.Mvc.csproj" />
<ProjectReference Include="..\..\src\Volo.Abp.Autofac\Volo.Abp.Autofac.csproj" />
<ProjectReference Include="..\Volo.Abp.AspNetCore.Tests\Volo.Abp.AspNetCore.Tests.csproj" />
<ProjectReference Include="..\Volo.Abp.MemoryDb.Tests\Volo.Abp.MemoryDb.Tests.csproj" />
</ItemGroup>
</Project>

@ -1,19 +1,31 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AspNetCore.Modularity;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.TestBase;
using Volo.Abp.Autofac;
using Volo.Abp.MemoryDb;
using Volo.Abp.Modularity;
using Volo.Abp.TestApp;
namespace Volo.Abp.AspNetCore.App
{
[DependsOn(
typeof(AbpAspNetCoreTestBaseModule)
typeof(AbpAspNetCoreTestBaseModule),
typeof(AbpMemoryDbTestModule),
typeof(AbpAspNetCoreMvcModule),
typeof(AbpAutofacModule)
)]
public class AppModule : AbpModule
{
public override void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.Configure<AbpAspNetCoreMvcOptions>(options =>
{
options.CreateControllersForAppServices(typeof(TestAppModule).Assembly);
});
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)

@ -17,7 +17,6 @@ namespace Volo.Abp.AspNetCore.App
//TODO: This is needed because ASP.NET Core does not use IServiceProviderFactory!
return services.BuildServiceProviderFromFactory();
//return services.BuildServiceProvider();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)

@ -0,0 +1,18 @@
using Shouldly;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.TestApp.Application;
using Xunit;
namespace Volo.Abp.AspNetCore.Mvc
{
public class PersonAppService_Tests : AspNetCoreMvcTestBase
{
[Fact]
public async Task GetAll_Test()
{
var result = await GetResponseAsObjectAsync<ListResultDto<PersonDto>>("/api/services/app/person/GetAll");
result.Items.Count.ShouldBeGreaterThan(0);
}
}
}
Loading…
Cancel
Save