diff --git a/docs/Getting-Started-AspNetCore-Application.md b/docs/Getting-Started-AspNetCore-Application.md index 5b040bc623..0dc0df84b0 100644 --- a/docs/Getting-Started-AspNetCore-Application.md +++ b/docs/Getting-Started-AspNetCore-Application.md @@ -40,8 +40,6 @@ namespace BasicAspNetCoreApplication { public override void ConfigureServices(IServiceCollection services) { - services.AddMvc(); - services.AddAssemblyOf(); } @@ -63,7 +61,7 @@ namespace BasicAspNetCoreApplication ``AppModule`` is a good name for the startup module for an application. -A module class can register services to Dependency Injection by overriding ``ConfigureServices`` method as shown here. ``AddAssemblyOf<...>`` is a special extension method of ABP that registers all services in an assembly by convention (TODO: link to DI document). While this is optional, a module generally registers some services. +A module class can register services to Dependency Injection by overriding ``ConfigureServices`` method as shown here. ``AddAssemblyOf<...>`` is a special extension method of ABP that registers all services in an assembly by convention (see [dependency injection document](Dependency-Injection.md)). While this is optional, a module generally registers some services. ABP packages define module classes and a module can depend on another module. In the code above, our ``AppModule`` depends on ``AbpAspNetCoreMvcModule`` (defined by Volo.Abp.AspNetCore.Mvc package). It's common to add a ``DependsOn`` attribute after installing a new ABP nuget package. diff --git a/src/AbpDesk/AbpDesk.Web.Mvc/AbpDeskWebMvcModule.cs b/src/AbpDesk/AbpDesk.Web.Mvc/AbpDeskWebMvcModule.cs index 1a219bf861..e6f0c74ec2 100644 --- a/src/AbpDesk/AbpDesk.Web.Mvc/AbpDeskWebMvcModule.cs +++ b/src/AbpDesk/AbpDesk.Web.Mvc/AbpDeskWebMvcModule.cs @@ -39,6 +39,19 @@ namespace AbpDesk.Web.Mvc )] public class AbpDeskWebMvcModule : AbpModule //TODO: Rename to AbpDeskWebModule, change default namespace to AbpDesk.Web { + public override void PreConfigureServices(IServiceCollection services) + { + services.PreConfigure(builder => + { + builder + .AddViewLocalization() + .AddRazorPagesOptions(options => + { + options.Conventions.AuthorizeFolder("/App"); + }); + }); + } + public override void ConfigureServices(IServiceCollection services) { var hostingEnvironment = services.GetSingletonInstance(); @@ -53,13 +66,6 @@ namespace AbpDesk.Web.Mvc //services.Configure(configuration); //Needed when we use Volo.Abp.Identity.HttpApi.Client - services.AddMvc() //TODO: Move to AbpAspNetCoreMvcModule! - .AddViewLocalization() - .AddRazorPagesOptions(options => - { - options.Conventions.AuthorizeFolder("/App"); - }); - services.AddAssemblyOf(); services.Configure(options => @@ -78,7 +84,6 @@ namespace AbpDesk.Web.Mvc var env = services.GetSingletonInstance(); //TODO: Find a better way! - if (env.IsDevelopment()) { services.Configure(options => diff --git a/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs b/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs index 3dcd956bf6..4a611f780f 100644 --- a/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs +++ b/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs @@ -64,12 +64,13 @@ namespace Volo.Abp.AspNetCore.Mvc }); }); - services.AddAssemblyOf(); - } + var mvcCoreBuilder = services.AddMvcCore(); + services.GetPreConfigureActions().Configure(mvcCoreBuilder); - public override void PostConfigureServices(IServiceCollection services) - { - //TODO: Consider to use services.AddMvc() and move this to ConfigureServices method! And also use .AddControllersAsServices and .AddViewComponentsAsServices... + var mvcBuilder = services.AddMvc().AddControllersAsServices(); + services.GetPreConfigureActions().Configure(mvcBuilder); + + //TODO: AddLocalization and AddViewLocalization by default..? services.TryAddSingleton(); services.TryAddSingleton(); @@ -90,6 +91,8 @@ namespace Volo.Abp.AspNetCore.Mvc { mvcOptions.AddAbp(services); }); + + services.AddAssemblyOf(); } public override void OnApplicationInitialization(ApplicationInitializationContext context) diff --git a/src/Volo.Abp.Identity.HttpApi.Host/AbpIdentityHttpApiHostModule.cs b/src/Volo.Abp.Identity.HttpApi.Host/AbpIdentityHttpApiHostModule.cs index db1f278d6b..333869058a 100644 --- a/src/Volo.Abp.Identity.HttpApi.Host/AbpIdentityHttpApiHostModule.cs +++ b/src/Volo.Abp.Identity.HttpApi.Host/AbpIdentityHttpApiHostModule.cs @@ -21,6 +21,17 @@ namespace Volo.Abp.Identity.HttpApi.Host [DependsOn(typeof(AbpIdentityHttpApiModule), typeof(AbpIdentityEntityFrameworkCoreModule), typeof(AbpAutofacModule))] public class AbpIdentityHttpApiHostModule : AbpModule { + public override void PreConfigureServices(IServiceCollection services) + { + services.PreConfigure(builder => + { + // add the versioned api explorer, which also adds IApiVersionDescriptionProvider service + // note: the specified format code will format the version as "'v'major[.minor][-status]" + + builder.AddVersionedApiExplorer(o => o.GroupNameFormat = "'v'VVV"); + }); + } + public override void ConfigureServices(IServiceCollection services) { var hostingEnvironment = services.GetSingletonInstance(); //TOD: Move to BuildConfiguration method @@ -37,15 +48,6 @@ namespace Volo.Abp.Identity.HttpApi.Host }); }); - // add the versioned api explorer, which also adds IApiVersionDescriptionProvider service - // note: the specified format code will format the version as "'v'major[.minor][-status]" - services.AddMvcCore().AddVersionedApiExplorer(o => o.GroupNameFormat = "'v'VVV"); - - services.AddMvc(options => - { - - }); - services.AddApiVersioning(o => { o.ReportApiVersions = true; diff --git a/src/Volo.Abp/Microsoft/Extensions/DependencyInjection/ServiceCollectionPreConfigureExtensions.cs b/src/Volo.Abp/Microsoft/Extensions/DependencyInjection/ServiceCollectionPreConfigureExtensions.cs new file mode 100644 index 0000000000..c5f9c68814 --- /dev/null +++ b/src/Volo.Abp/Microsoft/Extensions/DependencyInjection/ServiceCollectionPreConfigureExtensions.cs @@ -0,0 +1,27 @@ +using System; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Options; + +namespace Microsoft.Extensions.DependencyInjection +{ + public static class ServiceCollectionPreConfigureExtensions + { + public static IServiceCollection PreConfigure(this IServiceCollection services, Action optionsAction) + { + services.GetPreConfigureActions().Add(optionsAction); + return services; + } + + public static PreConfigureActionList GetPreConfigureActions(this IServiceCollection services) + { + var actionList = services.GetSingletonInstanceOrNull>>()?.Value; + if (actionList == null) + { + actionList = new PreConfigureActionList(); + services.AddObjectAccessor(actionList); + } + + return actionList; + } + } +} diff --git a/src/Volo.Abp/Volo/Abp/Options/PreConfigureActionList.cs b/src/Volo.Abp/Volo/Abp/Options/PreConfigureActionList.cs new file mode 100644 index 0000000000..00222d6399 --- /dev/null +++ b/src/Volo.Abp/Volo/Abp/Options/PreConfigureActionList.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; + +namespace Volo.Abp.Options +{ + public class PreConfigureActionList : List> + { + public void Configure(TOptions options) + { + foreach (var action in this) + { + action(options); + } + } + } +} \ No newline at end of file diff --git a/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs b/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs index 6e3bc29da5..5a58e47fb2 100644 --- a/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs +++ b/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs @@ -18,10 +18,17 @@ namespace Volo.Abp.AspNetCore.Mvc )] public class AbpAspNetCoreMvcTestModule : AbpModule { + public override void PreConfigureServices(IServiceCollection services) + { + services.PreConfigure(builder => + { + builder.AddViewLocalization(); + }); + } + public override void ConfigureServices(IServiceCollection services) { - services.AddLocalization(); //TODO: Move to AbpAspNetCoreMvcModule - services.AddMvc().AddViewLocalization(); //TODO: Move to AbpAspNetCoreMvcModule + services.AddLocalization(); //TODO: Move to the framework..? services.Configure(options => { diff --git a/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/AbpAspNetCoreMvcVersioningTestModule.cs b/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/AbpAspNetCoreMvcVersioningTestModule.cs index ad035e8edd..b620de88c3 100644 --- a/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/AbpAspNetCoreMvcVersioningTestModule.cs +++ b/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/AbpAspNetCoreMvcVersioningTestModule.cs @@ -1,6 +1,5 @@ using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.Versioning; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.AspNetCore.Modularity; using Volo.Abp.AspNetCore.TestBase; @@ -20,8 +19,6 @@ namespace Volo.Abp.AspNetCore.Mvc.Versioning { public override void ConfigureServices(IServiceCollection services) { - services.AddMvc(); - services.Configure(options => { //2.0 Version