diff --git a/docs/en/Getting-Started-AspNetCore-Application.md b/docs/en/Getting-Started-AspNetCore-Application.md index c5b72a6c1d..0ccd900b1f 100644 --- a/docs/en/Getting-Started-AspNetCore-Application.md +++ b/docs/en/Getting-Started-AspNetCore-Application.md @@ -77,20 +77,17 @@ using BasicAspNetCoreApplication; var builder = WebApplication.CreateBuilder(args); -builder.Services.ReplaceConfiguration(builder.Configuration); - -builder.Services.AddApplication(); +await builder.Services.AddApplicationAsync(); var app = builder.Build(); -app.InitializeApplication(); - -app.Run(); +await app.InitializeApplicationAsync(); +await app.RunAsync(); ```` -``builder.Services.AddApplication();`` adds all services defined in all modules starting from the ``AppModule``. +``builder.Services.AddApplicationAsync();`` adds all services defined in all modules starting from the ``AppModule``. -``app.InitializeApplication()`` initializes and starts the application. +``app.InitializeApplicationAsync()`` initializes and starts the application. ## Run the Application! @@ -98,9 +95,9 @@ That's all! Run the application, it will just work as expected. ## Using Autofac as the Dependency Injection Framework -While AspNet Core's Dependency Injection (DI) system is fine for basic requirements, [Autofac](https://autofac.org/) provides advanced features like Property Injection and Method Interception which are required by ABP to perform advanced application framework features. +While ASP.NET Core's Dependency Injection (DI) system is fine for basic requirements, [Autofac](https://autofac.org/) provides advanced features like Property Injection and Method Interception which are required by ABP to perform advanced application framework features. -Replacing AspNet Core's DI system by Autofac and integrating to ABP is pretty easy. +Replacing ASP.NET Core's DI system by Autofac and integrating to ABP is pretty easy. 1. Install [Volo.Abp.Autofac](https://www.nuget.org/packages/Volo.Abp.Autofac) package @@ -128,19 +125,14 @@ var builder = WebApplication.CreateBuilder(args); builder.Host.UseAutofac(); //Add this line -builder.Services.ReplaceConfiguration(builder.Configuration); - -builder.Services.AddApplication(); +await builder.Services.AddApplicationAsync(); var app = builder.Build(); -app.InitializeApplication(); - -app.Run(); - +await app.InitializeApplicationAsync(); +await app.RunAsync(); ```` ## Source Code Get source code of the sample project created in this tutorial from [here](https://github.com/abpframework/abp-samples/tree/master/BasicAspNetCoreApplication). - diff --git a/docs/en/Module-Development-Basics.md b/docs/en/Module-Development-Basics.md index 63cbc31893..dd01f81ff4 100644 --- a/docs/en/Module-Development-Basics.md +++ b/docs/en/Module-Development-Basics.md @@ -29,6 +29,8 @@ public class BlogModule : AbpModule ``ConfigureServices`` is the main method to add your services to the dependency injection system and configure other modules. Example: +> These methods have Async versions too, and if you want to make asynchronous calls inside these methods, override the asynchronous versions instead of the synchronous ones. + ````C# public class BlogModule : AbpModule { @@ -57,26 +59,31 @@ public class BlogModule : AbpModule } ```` +> `ConfigureServices` method has an asynchronous version too: `ConfigureServicesAsync`. If you want to make asynchronous calls (use the `await` keyword) inside this method, override the asynchronous version instead of the synchronous one. If you override both asynchronous and synchronous versions, only the asynchronous version will be executed. + See the [Configuration](Configuration.md) document for more about the configuration system. #### Pre & Post Configure Services ``AbpModule`` class also defines ``PreConfigureServices`` and ``PostConfigureServices`` methods to override and write your code just before and just after ``ConfigureServices``. Notice that the code you have written into these methods will be executed before/after the ``ConfigureServices`` methods of all other modules. +> These methods have asynchronous versions too. If you want to make asynchronous calls inside these methods, override the asynchronous versions instead of the synchronous ones. + ### Application Initialization Once all the services of all modules are configured, the application starts by initializing all modules. In this phase, you can resolve services from ``IServiceProvider`` since it's ready and available. #### OnApplicationInitialization Method -You can override ``OnApplicationInitialization`` method to execute code while application is being started. Example: +You can override ``OnApplicationInitialization`` method to execute code while application is being started. + +**Example:** ````C# public class BlogModule : AbpModule { - //... - - public override void OnApplicationInitialization(ApplicationInitializationContext context) + public override void OnApplicationInitialization( + ApplicationInitializationContext context) { var myService = context.ServiceProvider.GetService(); myService.DoSomething(); @@ -84,14 +91,32 @@ public class BlogModule : AbpModule } ```` -``OnApplicationInitialization`` is generally used by the startup module to construct the middleware pipeline for ASP.NET Core applications. Example: +`OnApplicationInitialization` method has an asynchronous version too. If you want to make asynchronous calls (use the `await` keyword) inside this method, override the asynchronous version instead of the synchronous one. + +**Example:** + +````csharp +public class BlogModule : AbpModule +{ + public override Task OnApplicationInitializationAsync( + ApplicationInitializationContext context) + { + var myService = context.ServiceProvider.GetService(); + await myService.DoSomethingAsync(); + } +} +```` + +> If you override both asynchronous and synchronous versions, only the asynchronous version will be executed. + +``OnApplicationInitialization`` is generally used by the startup module to construct the middleware pipeline for ASP.NET Core applications. + +**Example:** ````C# [DependsOn(typeof(AbpAspNetCoreMvcModule))] public class AppModule : AbpModule { - //... - public override void OnApplicationInitialization(ApplicationInitializationContext context) { var app = context.GetApplicationBuilder(); @@ -113,10 +138,14 @@ You can also perform startup logic if your module requires it ``AbpModule`` class also defines ``OnPreApplicationInitialization`` and ``OnPostApplicationInitialization`` methods to override and write your code just before and just after ``OnApplicationInitialization``. Notice that the code you have written into these methods will be executed before/after the ``OnApplicationInitialization`` methods of all other modules. +> These methods have asynchronous versions too, and if you want to make asynchronous calls inside these methods, override the asynchronous versions instead of the synchronous ones. + ### Application Shutdown Lastly, you can override ``OnApplicationShutdown`` method if you want to execute some code while application is being shutdown. +> This methods has asynchronous version too. If you want to make asynchronous calls inside this method, override the asynchronous version instead of the synchronous one. + ## Module Dependencies In a modular application, it's not unusual for one module to depend upon another module(s). An Abp module must declare ``[DependsOn]`` attribute if it does have a dependency upon another module, as shown below: diff --git a/docs/en/_deleted/Bootstrap-Modules.md b/docs/en/_deleted/Bootstrap-Modules.md new file mode 100644 index 0000000000..904197e4e3 --- /dev/null +++ b/docs/en/_deleted/Bootstrap-Modules.md @@ -0,0 +1,128 @@ +# Bootstrap Modules + +ABP framework can be bootstrapped in various applications. like ASP NET Core or Console, WPF, etc. + +Modules can be started sync or async, Corresponds to various event methods in the module. We recommend using **async**, Especially if you want to make async calls in the module's methods. + +The `PreConfigureServices`, `ConfigureServices`, `PostConfigureServices`, `OnPreApplicationInitialization`, `OnApplicationInitialization`, `OnPostApplicationInitialization` methods of module have the Async version. + +> Async methods automatically call sync methods by default. + +If you use async methods in your module, please keep the same sync methods for compatibility. + +````csharp +public async override Task OnApplicationInitializationAsync(ApplicationInitializationContext context) +{ + await AsyncMethod(); +} + +public override void OnApplicationInitialization(ApplicationInitializationContext context) +{ + AsyncHelper.RunSync(() => OnApplicationInitializationAsync(context)); +} +```` + +## ASP NET Core + +Bootstrap ABP by using [WebApplication](https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.builder.webapplication?view=aspnetcore-6.0) + +````csharp +var builder = WebApplication.CreateBuilder(args); +builder.Host.AddAppSettingsSecretsJson() + .UseAutofac(); + +await builder.Services.AddApplicationAsync(); +var app = builder.Build(); + +await app.InitializeApplicationAsync(); +await app.RunAsync(); +```` + +## Console + +Bootstrap ABP in Console App. + +````csharp +var abpApplication = await AbpApplicationFactory.CreateAsync(options => +{ + options.UseAutofac(); +}); + +await _abpApplication.InitializeAsync(); + +var helloWorldService = _abpApplication.ServiceProvider.GetRequiredService(); + +await helloWorldService.SayHelloAsync(); +```` + +Bootstrap ABP by using [HostedService](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-6.0&tabs=visual-studio#ihostedservice-interface) + +````csharp +public class MyHostedService : IHostedService +{ + private IAbpApplicationWithInternalServiceProvider _abpApplication; + + private readonly IConfiguration _configuration; + private readonly IHostEnvironment _hostEnvironment; + + public MyHostedService(IConfiguration configuration, IHostEnvironment hostEnvironment) + { + _configuration = configuration; + _hostEnvironment = hostEnvironment; + } + + public async Task StartAsync(CancellationToken cancellationToken) + { + _abpApplication = await AbpApplicationFactory.CreateAsync(options => + { + options.Services.ReplaceConfiguration(_configuration); + options.Services.AddSingleton(_hostEnvironment); + + options.UseAutofac(); + options.Services.AddLogging(loggingBuilder => loggingBuilder.AddSerilog()); + }); + + await _abpApplication.InitializeAsync(); + + var helloWorldService = _abpApplication.ServiceProvider.GetRequiredService(); + + await helloWorldService.SayHelloAsync(); + } + + public async Task StopAsync(CancellationToken cancellationToken) + { + await _abpApplication.ShutdownAsync(); + } +} +```` + +## WPF + +Bootstrap ABP on [OnStartup](https://docs.microsoft.com/en-us/dotnet/api/system.windows.application.onstartup?view=windowsdesktop-6.0) method. + +````csharp +public partial class App : Application +{ + private IAbpApplicationWithInternalServiceProvider _abpApplication; + + protected async override void OnStartup(StartupEventArgs e) + { + _abpApplication = await AbpApplicationFactory.CreateAsync(options => + { + options.UseAutofac(); + options.Services.AddLogging(loggingBuilder => loggingBuilder.AddSerilog(dispose: true)); + }); + + await _abpApplication.InitializeAsync(); + + _abpApplication.Services.GetRequiredService()?.Show(); + } + + protected async override void OnExit(ExitEventArgs e) + { + await _abpApplication.ShutdownAsync(); + } +} + +```` +