diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json index 7bb8f4d109..9720354d99 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json @@ -193,7 +193,7 @@ "WhatHappensWhenLicenseEnds": "What happens when my license period ends?", "WhatHappensWhenLicenseEndsExplanation1": "ABP Commercial license type is perpetual license. After your license expires, you can continue developing your project. And you are not obliged to renew your license. Your license comes with a one-year Updates and Support plan out of the box. To continue to receive new features, performance enhancements, bug fixes, support and continue to use ABP Suite, make sure to renew your plan each year. When your license expires, you will not be able to get more of the following benefits;", "WhatHappensWhenLicenseEndsExplanation2": "You can not create new solutions using the ABP Commercial, but you can continue to develop your existing applications forever.", - "WhatHappensWhenLicenseEndsExplanation3": "You will be able to get updates for the modules and themes within your MAJOR version. For example; if you are using v3.2.0 of a module, you can still get updates for v3.x.x (v3.3.0, v3.5.2... etc.) of that module. But you cannot get updates for the next major version (like v4.x, v5.x)", + "WhatHappensWhenLicenseEndsExplanation3": "You will be able to get updates for the modules and themes within your MAJOR version (except RC or Preview versions). For example; if you are using v3.2.0 of a module, you can still get updates for v3.x.x (v3.3.0, v3.5.2... etc.) of that module. But you cannot get updates for the next major version (like v4.x, v5.x). Let's say, when your license expired, the latest release was v4.4.3 and the latest preview version was v5.0.0-rc.2, you can only access the v4.X.X but you cannot access the v5.X.X.", "WhatHappensWhenLicenseEndsExplanation4": "You can not install new modules and themes added to the ABP Commercial platform after your license ends.", "WhatHappensWhenLicenseEndsExplanation5": "You can not use the ABP Suite.", "WhatHappensWhenLicenseEndsExplanation6": "You can not get the premium support anymore.", diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Microsoft/AspNetCore/Components/WebAssembly/Hosting/AbpWebAssemblyHostBuilderExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Microsoft/AspNetCore/Components/WebAssembly/Hosting/AbpWebAssemblyHostBuilderExtensions.cs index cb104533cb..7c4ff4a868 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Microsoft/AspNetCore/Components/WebAssembly/Hosting/AbpWebAssemblyHostBuilderExtensions.cs +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Microsoft/AspNetCore/Components/WebAssembly/Hosting/AbpWebAssemblyHostBuilderExtensions.cs @@ -17,6 +17,30 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Hosting; public static class AbpWebAssemblyHostBuilderExtensions { + public static async Task AddApplicationAsync( + [NotNull] this WebAssemblyHostBuilder builder, + Action options) + where TStartupModule : IAbpModule + { + Check.NotNull(builder, nameof(builder)); + + // Related this commit(https://github.com/dotnet/aspnetcore/commit/b99d805bc037fcac56afb79abeb7d5a43141c85e) + // Microsoft.AspNetCore.Blazor.BuildTools has been removed in net 5.0. + // This call may be removed when we find a suitable solution. + // System.Runtime.CompilerServices.AsyncStateMachineAttribute + Castle.DynamicProxy.Generators.AttributesToAvoidReplicating.Add(); + + builder.Services.AddSingleton(builder.Configuration); + builder.Services.AddSingleton(builder); + + var application = await builder.Services.AddApplicationAsync(opts => + { + options?.Invoke(new AbpWebAssemblyApplicationCreationOptions(builder, opts)); + }); + + return application; + } + public static IAbpApplicationWithExternalServiceProvider AddApplication( [NotNull] this WebAssemblyHostBuilder builder, Action options) @@ -51,7 +75,7 @@ public static class AbpWebAssemblyHostBuilderExtensions ((ComponentsClientScopeServiceProviderAccessor)serviceProvider .GetRequiredService()).ServiceProvider = serviceProvider; - application.Initialize(serviceProvider); + await application.InitializeAsync(serviceProvider); await InitializeModulesAsync(serviceProvider); await SetCurrentLanguageAsync(serviceProvider); } diff --git a/framework/src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/AbpAspNetCoreAsyncIntegratedTestBase.cs b/framework/src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/AbpAspNetCoreAsyncIntegratedTestBase.cs new file mode 100644 index 0000000000..3f5e9ad4b8 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/AbpAspNetCoreAsyncIntegratedTestBase.cs @@ -0,0 +1,112 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting.Server; +using Microsoft.AspNetCore.Routing; +using Microsoft.AspNetCore.TestHost; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Volo.Abp.Modularity; + +namespace Volo.Abp.AspNetCore.TestBase; + +public class AbpAspNetCoreAsyncIntegratedTestBase + where TModule : IAbpModule +{ + protected WebApplication WebApplication { get; set; } + + protected TestServer Server { get; set; } + + protected HttpClient Client { get; set; } + + protected IServiceProvider ServiceProvider { get; set; } + + protected virtual T GetService() + { + return ServiceProvider.GetService(); + } + + protected virtual T GetRequiredService() + { + return ServiceProvider.GetRequiredService(); + } + + public virtual async Task InitializeAsync() + { + var builder = WebApplication.CreateBuilder(); + builder.Host.ConfigureServices(services => + { + services.AddSingleton(); + services.AddSingleton(); + }) + .UseAutofac(); + + await builder.Services.AddApplicationAsync(options => + { + options.Services.ReplaceConfiguration(builder.Configuration); + }); + + await ConfigureServicesAsync(builder.Services); + WebApplication = builder.Build(); + await WebApplication.InitializeApplicationAsync(); + await WebApplication.StartAsync(); + + Server = WebApplication.Services.GetRequiredService().GetTestServer(); + Client = Server.CreateClient(); + + ServiceProvider = Server.Services; + ServiceProvider.GetRequiredService().Server = Server; + } + + public virtual async Task DisposeAsync() + { + await WebApplication.DisposeAsync(); + } + + protected virtual Task ConfigureServicesAsync(IServiceCollection services) + { + return Task.CompletedTask; + } + + #region GetUrl + + /// + /// Gets default URL for given controller type. + /// + /// The type of the controller. + protected virtual string GetUrl() + { + return "/" + typeof(TController).Name.RemovePostFix("Controller", "AppService", "ApplicationService", "Service"); + } + + /// + /// Gets default URL for given controller type's given action. + /// + /// The type of the controller. + protected virtual string GetUrl(string actionName) + { + return GetUrl() + "/" + actionName; + } + + /// + /// Gets default URL for given controller type's given action with query string parameters (as anonymous object). + /// + /// The type of the controller. + protected virtual string GetUrl(string actionName, object queryStringParamsAsAnonymousObject) + { + var url = GetUrl(actionName); + + var dictionary = new RouteValueDictionary(queryStringParamsAsAnonymousObject); + if (dictionary.Any()) + { + url += "?" + dictionary.Select(d => $"{d.Key}={d.Value}").JoinAsString("&"); + } + + return url; + } + + #endregion +} diff --git a/framework/src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/AbpAspNetCoreIntegratedTestBase.cs b/framework/src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/AbpAspNetCoreIntegratedTestBase.cs index 1fa62b2417..f3e60979bb 100644 --- a/framework/src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/AbpAspNetCoreIntegratedTestBase.cs +++ b/framework/src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/AbpAspNetCoreIntegratedTestBase.cs @@ -17,8 +17,6 @@ public abstract class AbpAspNetCoreIntegratedTestBase : AbpTestBaseWit protected HttpClient Client { get; } - protected override IServiceProvider ServiceProvider { get; } - private readonly IHost _host; protected AbpAspNetCoreIntegratedTestBase() diff --git a/framework/src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/TestNoopHostLifetime.cs b/framework/src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/TestNoopHostLifetime.cs new file mode 100644 index 0000000000..a0fe2d46c1 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/TestNoopHostLifetime.cs @@ -0,0 +1,18 @@ +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Hosting; + +namespace Volo.Abp.AspNetCore.TestBase; + +public class TestNoopHostLifetime : IHostLifetime +{ + public Task StopAsync(CancellationToken cancellationToken) + { + return Task.CompletedTask; + } + + public Task WaitForStartAsync(CancellationToken cancellationToken) + { + return Task.CompletedTask; + } +} diff --git a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpApplicationBuilderExtensions.cs b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpApplicationBuilderExtensions.cs index 2e8b221b3c..8ef3ec8d99 100644 --- a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpApplicationBuilderExtensions.cs +++ b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpApplicationBuilderExtensions.cs @@ -1,4 +1,5 @@ using System; +using System.Threading.Tasks; using JetBrains.Annotations; using Microsoft.AspNetCore.RequestLocalization; using Microsoft.Extensions.DependencyInjection; @@ -11,6 +12,7 @@ using Volo.Abp.AspNetCore.Security.Claims; using Volo.Abp.AspNetCore.Tracing; using Volo.Abp.AspNetCore.Uow; using Volo.Abp.DependencyInjection; +using Volo.Abp.Threading; namespace Microsoft.AspNetCore.Builder; @@ -18,6 +20,27 @@ public static class AbpApplicationBuilderExtensions { private const string ExceptionHandlingMiddlewareMarker = "_AbpExceptionHandlingMiddleware_Added"; + public async static Task InitializeApplicationAsync([NotNull] this IApplicationBuilder app) + { + Check.NotNull(app, nameof(app)); + + app.ApplicationServices.GetRequiredService>().Value = app; + var application = app.ApplicationServices.GetRequiredService(); + var applicationLifetime = app.ApplicationServices.GetRequiredService(); + + applicationLifetime.ApplicationStopping.Register(() => + { + AsyncHelper.RunSync(() => application.ShutdownAsync()); + }); + + applicationLifetime.ApplicationStopped.Register(() => + { + application.Dispose(); + }); + + await application.InitializeAsync(app.ApplicationServices); + } + public static void InitializeApplication([NotNull] this IApplicationBuilder app) { Check.NotNull(app, nameof(app)); diff --git a/framework/src/Volo.Abp.BackgroundJobs.RabbitMQ/Volo/Abp/BackgroundJobs/RabbitMQ/AbpBackgroundJobsRabbitMqModule.cs b/framework/src/Volo.Abp.BackgroundJobs.RabbitMQ/Volo/Abp/BackgroundJobs/RabbitMQ/AbpBackgroundJobsRabbitMqModule.cs index 33cbc740e4..c601ca5549 100644 --- a/framework/src/Volo.Abp.BackgroundJobs.RabbitMQ/Volo/Abp/BackgroundJobs/RabbitMQ/AbpBackgroundJobsRabbitMqModule.cs +++ b/framework/src/Volo.Abp.BackgroundJobs.RabbitMQ/Volo/Abp/BackgroundJobs/RabbitMQ/AbpBackgroundJobsRabbitMqModule.cs @@ -1,4 +1,5 @@ -using Microsoft.Extensions.DependencyInjection; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Modularity; using Volo.Abp.RabbitMQ; using Volo.Abp.Threading; @@ -17,31 +18,37 @@ public class AbpBackgroundJobsRabbitMqModule : AbpModule context.Services.AddSingleton(typeof(IJobQueue<>), typeof(JobQueue<>)); } + public async override Task OnApplicationInitializationAsync(ApplicationInitializationContext context) + { + await StartJobQueueManagerAsync(context); + } + + public async override Task OnApplicationShutdownAsync(ApplicationShutdownContext context) + { + await StopJobQueueManagerAsync(context); + } + public override void OnApplicationInitialization(ApplicationInitializationContext context) { - StartJobQueueManager(context); + AsyncHelper.RunSync(() => StartJobQueueManagerAsync(context)); } public override void OnApplicationShutdown(ApplicationShutdownContext context) { - StopJobQueueManager(context); + AsyncHelper.RunSync(() => StopJobQueueManagerAsync(context)); } - private static void StartJobQueueManager(ApplicationInitializationContext context) + private async static Task StartJobQueueManagerAsync(ApplicationInitializationContext context) { - AsyncHelper.RunSync( - () => context.ServiceProvider - .GetRequiredService() - .StartAsync() - ); + await context.ServiceProvider + .GetRequiredService() + .StartAsync(); } - private static void StopJobQueueManager(ApplicationShutdownContext context) + private async static Task StopJobQueueManagerAsync(ApplicationShutdownContext context) { - AsyncHelper.RunSync( - () => context.ServiceProvider - .GetRequiredService() - .StopAsync() - ); + await context.ServiceProvider + .GetRequiredService() + .StopAsync(); } } diff --git a/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/AbpBackgroundJobsModule.cs b/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/AbpBackgroundJobsModule.cs index aaa4a7ba01..47a165ca83 100644 --- a/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/AbpBackgroundJobsModule.cs +++ b/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/AbpBackgroundJobsModule.cs @@ -1,9 +1,11 @@ -using Microsoft.Extensions.DependencyInjection; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Volo.Abp.BackgroundWorkers; using Volo.Abp.DistributedLocking; using Volo.Abp.Guids; using Volo.Abp.Modularity; +using Volo.Abp.Threading; using Volo.Abp.Timing; namespace Volo.Abp.BackgroundJobs; @@ -17,12 +19,21 @@ namespace Volo.Abp.BackgroundJobs; )] public class AbpBackgroundJobsModule : AbpModule { + public async override Task OnApplicationInitializationAsync(ApplicationInitializationContext context) + { + var options = context.ServiceProvider.GetRequiredService>().Value; + if (options.IsJobExecutionEnabled) + { + await context.AddBackgroundWorkerAsync(); + } + } + public override void OnApplicationInitialization(ApplicationInitializationContext context) { var options = context.ServiceProvider.GetRequiredService>().Value; if (options.IsJobExecutionEnabled) { - context.AddBackgroundWorker(); + AsyncHelper.RunSync(() => context.AddBackgroundWorkerAsync()); } } } diff --git a/framework/src/Volo.Abp.BackgroundWorkers.Hangfire/Volo/Abp/BackgroundWorkers/Hangfire/HangfireBackgroundWorkerManager.cs b/framework/src/Volo.Abp.BackgroundWorkers.Hangfire/Volo/Abp/BackgroundWorkers/Hangfire/HangfireBackgroundWorkerManager.cs index acd47598bc..ab1cd461e7 100644 --- a/framework/src/Volo.Abp.BackgroundWorkers.Hangfire/Volo/Abp/BackgroundWorkers/Hangfire/HangfireBackgroundWorkerManager.cs +++ b/framework/src/Volo.Abp.BackgroundWorkers.Hangfire/Volo/Abp/BackgroundWorkers/Hangfire/HangfireBackgroundWorkerManager.cs @@ -21,7 +21,7 @@ public class HangfireBackgroundWorkerManager : IBackgroundWorkerManager, ISingle return Task.CompletedTask; } - public void Add(IBackgroundWorker worker) + public async Task AddAsync(IBackgroundWorker worker) { if (worker is IHangfireBackgroundWorker hangfireBackgroundWorker) { diff --git a/framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/AbpBackgroundWorkersQuartzModule.cs b/framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/AbpBackgroundWorkersQuartzModule.cs index 5884532f1e..07586b461b 100644 --- a/framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/AbpBackgroundWorkersQuartzModule.cs +++ b/framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/AbpBackgroundWorkersQuartzModule.cs @@ -5,6 +5,7 @@ using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Options; using Volo.Abp.Modularity; using Volo.Abp.Quartz; +using Volo.Abp.Threading; namespace Volo.Abp.BackgroundWorkers.Quartz; @@ -34,6 +35,21 @@ public class AbpBackgroundWorkersQuartzModule : AbpModule } } + public async override Task OnApplicationInitializationAsync(ApplicationInitializationContext context) + { + var quartzBackgroundWorkerOptions = context.ServiceProvider.GetRequiredService>().Value; + if (quartzBackgroundWorkerOptions.IsAutoRegisterEnabled) + { + var backgroundWorkerManager = context.ServiceProvider.GetRequiredService(); + var works = context.ServiceProvider.GetServices().Where(x => x.AutoRegister); + + foreach (var work in works) + { + await backgroundWorkerManager.AddAsync(work); + } + } + } + public override void OnApplicationInitialization(ApplicationInitializationContext context) { var quartzBackgroundWorkerOptions = context.ServiceProvider.GetRequiredService>().Value; @@ -44,7 +60,7 @@ public class AbpBackgroundWorkersQuartzModule : AbpModule foreach (var work in works) { - backgroundWorkerManager.Add(work); + AsyncHelper.RunSync(() => backgroundWorkerManager.AddAsync(work)); } } } diff --git a/framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/QuartzBackgroundWorkerManager.cs b/framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/QuartzBackgroundWorkerManager.cs index efee2d2139..954f21bcda 100644 --- a/framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/QuartzBackgroundWorkerManager.cs +++ b/framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/QuartzBackgroundWorkerManager.cs @@ -33,9 +33,9 @@ public class QuartzBackgroundWorkerManager : IBackgroundWorkerManager, ISingleto } } - public virtual void Add(IBackgroundWorker worker) + public virtual async Task AddAsync(IBackgroundWorker worker) { - AsyncHelper.RunSync(() => ReScheduleJobAsync(worker)); + await ReScheduleJobAsync(worker); } protected virtual async Task ReScheduleJobAsync(IBackgroundWorker worker) diff --git a/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/AbpBackgroundWorkersModule.cs b/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/AbpBackgroundWorkersModule.cs index 40c4a70fb1..32341f101e 100644 --- a/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/AbpBackgroundWorkersModule.cs +++ b/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/AbpBackgroundWorkersModule.cs @@ -1,4 +1,5 @@ -using Microsoft.Extensions.DependencyInjection; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Volo.Abp.Modularity; using Volo.Abp.Threading; @@ -10,6 +11,28 @@ namespace Volo.Abp.BackgroundWorkers; )] public class AbpBackgroundWorkersModule : AbpModule { + public async override Task OnApplicationInitializationAsync(ApplicationInitializationContext context) + { + var options = context.ServiceProvider.GetRequiredService>().Value; + if (options.IsEnabled) + { + await context.ServiceProvider + .GetRequiredService() + .StartAsync(); + } + } + + public async override Task OnApplicationShutdownAsync(ApplicationShutdownContext context) + { + var options = context.ServiceProvider.GetRequiredService>().Value; + if (options.IsEnabled) + { + await context.ServiceProvider + .GetRequiredService() + .StopAsync(); + } + } + public override void OnApplicationInitialization(ApplicationInitializationContext context) { var options = context.ServiceProvider.GetRequiredService>().Value; diff --git a/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/BackgroundWorkerManager.cs b/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/BackgroundWorkerManager.cs index 62c1f3607b..3276c837c0 100644 --- a/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/BackgroundWorkerManager.cs +++ b/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/BackgroundWorkerManager.cs @@ -26,15 +26,13 @@ public class BackgroundWorkerManager : IBackgroundWorkerManager, ISingletonDepen _backgroundWorkers = new List(); } - public virtual void Add(IBackgroundWorker worker) + public virtual async Task AddAsync(IBackgroundWorker worker) { _backgroundWorkers.Add(worker); if (IsRunning) { - AsyncHelper.RunSync( - () => worker.StartAsync() - ); + await worker.StartAsync(); } } diff --git a/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/BackgroundWorkersApplicationInitializationContextExtensions.cs b/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/BackgroundWorkersApplicationInitializationContextExtensions.cs index 5cff67b7de..9df0f6c5e4 100644 --- a/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/BackgroundWorkersApplicationInitializationContextExtensions.cs +++ b/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/BackgroundWorkersApplicationInitializationContextExtensions.cs @@ -1,4 +1,5 @@ using System; +using System.Threading.Tasks; using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection; @@ -6,17 +7,17 @@ namespace Volo.Abp.BackgroundWorkers; public static class BackgroundWorkersApplicationInitializationContextExtensions { - public static ApplicationInitializationContext AddBackgroundWorker([NotNull] this ApplicationInitializationContext context) + public async static Task AddBackgroundWorkerAsync([NotNull] this ApplicationInitializationContext context) where TWorker : IBackgroundWorker { Check.NotNull(context, nameof(context)); - context.AddBackgroundWorker(typeof(TWorker)); + await context.AddBackgroundWorkerAsync(typeof(TWorker)); return context; } - public static ApplicationInitializationContext AddBackgroundWorker([NotNull] this ApplicationInitializationContext context, [NotNull] Type workerType) + public async static Task AddBackgroundWorkerAsync([NotNull] this ApplicationInitializationContext context, [NotNull] Type workerType) { Check.NotNull(context, nameof(context)); Check.NotNull(workerType, nameof(workerType)); @@ -26,9 +27,9 @@ public static class BackgroundWorkersApplicationInitializationContextExtensions throw new AbpException($"Given type ({workerType.AssemblyQualifiedName}) must implement the {typeof(IBackgroundWorker).AssemblyQualifiedName} interface, but it doesn't!"); } - context.ServiceProvider + await context.ServiceProvider .GetRequiredService() - .Add( + .AddAsync( (IBackgroundWorker)context.ServiceProvider.GetRequiredService(workerType) ); diff --git a/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/IBackgroundWorkerManager.cs b/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/IBackgroundWorkerManager.cs index e1bf0e53f2..7f5268afff 100644 --- a/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/IBackgroundWorkerManager.cs +++ b/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/IBackgroundWorkerManager.cs @@ -1,4 +1,5 @@ -using Volo.Abp.Threading; +using System.Threading.Tasks; +using Volo.Abp.Threading; namespace Volo.Abp.BackgroundWorkers; @@ -13,5 +14,5 @@ public interface IBackgroundWorkerManager : IRunnable /// /// The worker. It should be resolved from IOC. /// - void Add(IBackgroundWorker worker); + Task AddAsync(IBackgroundWorker worker); } diff --git a/framework/src/Volo.Abp.Core/Microsoft/Extensions/DependencyInjection/ServiceCollectionApplicationExtensions.cs b/framework/src/Volo.Abp.Core/Microsoft/Extensions/DependencyInjection/ServiceCollectionApplicationExtensions.cs index 7748953cc4..ce4af2befa 100644 --- a/framework/src/Volo.Abp.Core/Microsoft/Extensions/DependencyInjection/ServiceCollectionApplicationExtensions.cs +++ b/framework/src/Volo.Abp.Core/Microsoft/Extensions/DependencyInjection/ServiceCollectionApplicationExtensions.cs @@ -1,4 +1,5 @@ using System; +using System.Threading.Tasks; using JetBrains.Annotations; using Volo.Abp; using Volo.Abp.Modularity; @@ -22,4 +23,20 @@ public static class ServiceCollectionApplicationExtensions { return AbpApplicationFactory.Create(startupModuleType, services, optionsAction); } + + public async static Task AddApplicationAsync( + [NotNull] this IServiceCollection services, + [CanBeNull] Action optionsAction = null) + where TStartupModule : IAbpModule + { + return await AbpApplicationFactory.CreateAsync(services, optionsAction); + } + + public async static Task AddApplicationAsync( + [NotNull] this IServiceCollection services, + [NotNull] Type startupModuleType, + [CanBeNull] Action optionsAction = null) + { + return await AbpApplicationFactory.CreateAsync(startupModuleType, services, optionsAction); + } } diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs b/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs index 85b1989445..2a73b72932 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; +using System.Threading.Tasks; using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -23,6 +24,8 @@ public abstract class AbpApplicationBase : IAbpApplication public IReadOnlyList Modules { get; } + private bool _configuredServices; + internal AbpApplicationBase( [NotNull] Type startupModuleType, [NotNull] IServiceCollection services, @@ -46,7 +49,21 @@ public abstract class AbpApplicationBase : IAbpApplication services.AddCoreAbpServices(this, options); Modules = LoadModules(services, options); - ConfigureServices(); + + if (!options.SkipConfigureServices) + { + ConfigureServices(); + } + } + + public virtual async Task ShutdownAsync() + { + using (var scope = ServiceProvider.CreateScope()) + { + await scope.ServiceProvider + .GetRequiredService() + .ShutdownModulesAsync(new ApplicationShutdownContext(scope.ServiceProvider)); + } } public virtual void Shutdown() @@ -70,6 +87,17 @@ public abstract class AbpApplicationBase : IAbpApplication ServiceProvider.GetRequiredService>().Value = ServiceProvider; } + protected virtual async Task InitializeModulesAsync() + { + using (var scope = ServiceProvider.CreateScope()) + { + WriteInitLogs(scope.ServiceProvider); + await scope.ServiceProvider + .GetRequiredService() + .InitializeModulesAsync(new ApplicationInitializationContext(scope.ServiceProvider)); + } + } + protected virtual void InitializeModules() { using (var scope = ServiceProvider.CreateScope()) @@ -111,8 +139,99 @@ public abstract class AbpApplicationBase : IAbpApplication } //TODO: We can extract a new class for this - protected virtual void ConfigureServices() + public virtual async Task ConfigureServicesAsync() + { + CheckMultipleConfigureServices(); + + var context = new ServiceConfigurationContext(Services); + Services.AddSingleton(context); + + foreach (var module in Modules) + { + if (module.Instance is AbpModule abpModule) + { + abpModule.ServiceConfigurationContext = context; + } + } + + //PreConfigureServices + foreach (var module in Modules.Where(m => m.Instance is IPreConfigureServices)) + { + try + { + await ((IPreConfigureServices)module.Instance).PreConfigureServicesAsync(context); + } + catch (Exception ex) + { + throw new AbpInitializationException($"An error occurred during {nameof(IPreConfigureServices.PreConfigureServicesAsync)} phase of the module {module.Type.AssemblyQualifiedName}. See the inner exception for details.", ex); + } + } + + var assemblies = new HashSet(); + + //ConfigureServices + foreach (var module in Modules) + { + if (module.Instance is AbpModule abpModule) + { + if (!abpModule.SkipAutoServiceRegistration) + { + var assembly = module.Type.Assembly; + if (!assemblies.Contains(assembly)) + { + Services.AddAssembly(assembly); + assemblies.Add(assembly); + } + } + } + + try + { + await module.Instance.ConfigureServicesAsync(context); + } + catch (Exception ex) + { + throw new AbpInitializationException($"An error occurred during {nameof(IAbpModule.ConfigureServicesAsync)} phase of the module {module.Type.AssemblyQualifiedName}. See the inner exception for details.", ex); + } + } + + //PostConfigureServices + foreach (var module in Modules.Where(m => m.Instance is IPostConfigureServices)) + { + try + { + await ((IPostConfigureServices)module.Instance).PostConfigureServicesAsync(context); + } + catch (Exception ex) + { + throw new AbpInitializationException($"An error occurred during {nameof(IPostConfigureServices.PostConfigureServicesAsync)} phase of the module {module.Type.AssemblyQualifiedName}. See the inner exception for details.", ex); + } + } + + foreach (var module in Modules) + { + if (module.Instance is AbpModule abpModule) + { + abpModule.ServiceConfigurationContext = null; + } + } + + _configuredServices = true; + } + + private void CheckMultipleConfigureServices() + { + if (_configuredServices) + { + throw new AbpInitializationException("Services have already been configured! If you call ConfigureServicesAsync method, you must have set AbpApplicationCreationOptions.SkipConfigureServices tu true before."); + } + } + + //TODO: We can extract a new class for this + public virtual void ConfigureServices() { + CheckMultipleConfigureServices(); + var context = new ServiceConfigurationContext(Services); Services.AddSingleton(context); @@ -185,5 +304,7 @@ public abstract class AbpApplicationBase : IAbpApplication abpModule.ServiceConfigurationContext = null; } } + + _configuredServices = true; } } diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationCreationOptions.cs b/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationCreationOptions.cs index ea2d69aae6..d18e43275b 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationCreationOptions.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationCreationOptions.cs @@ -19,6 +19,8 @@ public class AbpApplicationCreationOptions [NotNull] public AbpConfigurationBuilderOptions Configuration { get; } + public bool SkipConfigureServices { get; set; } + public AbpApplicationCreationOptions([NotNull] IServiceCollection services) { Services = Check.NotNull(services, nameof(services)); diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationFactory.cs b/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationFactory.cs index 13b886f1c3..50e5e862ca 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationFactory.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationFactory.cs @@ -1,4 +1,5 @@ using System; +using System.Threading.Tasks; using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Modularity; @@ -7,6 +8,60 @@ namespace Volo.Abp; public static class AbpApplicationFactory { + public async static Task CreateAsync( + [CanBeNull] Action optionsAction = null) + where TStartupModule : IAbpModule + { + var app = Create(typeof(TStartupModule), options => + { + optionsAction?.Invoke(options); + options.SkipConfigureServices = true; + }); + await app.ConfigureServicesAsync(); + return app; + } + + public async static Task CreateAsync( + [NotNull] Type startupModuleType, + [CanBeNull] Action optionsAction = null) + { + var app = new AbpApplicationWithInternalServiceProvider(startupModuleType, options => + { + optionsAction?.Invoke(options); + options.SkipConfigureServices = true; + }); + await app.ConfigureServicesAsync(); + return app; + } + + public async static Task CreateAsync( + [NotNull] IServiceCollection services, + [CanBeNull] Action optionsAction = null) + where TStartupModule : IAbpModule + { + var app = Create(typeof(TStartupModule), services, options => + { + optionsAction?.Invoke(options); + options.SkipConfigureServices = true; + }); + await app.ConfigureServicesAsync(); + return app; + } + + public async static Task CreateAsync( + [NotNull] Type startupModuleType, + [NotNull] IServiceCollection services, + [CanBeNull] Action optionsAction = null) + { + var app = new AbpApplicationWithExternalServiceProvider(startupModuleType, services, options => + { + optionsAction?.Invoke(options); + options.SkipConfigureServices = true; + }); + await app.ConfigureServicesAsync(); + return app; + } + public static IAbpApplicationWithInternalServiceProvider Create( [CanBeNull] Action optionsAction = null) where TStartupModule : IAbpModule diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationWithExternalServiceProvider.cs b/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationWithExternalServiceProvider.cs index 162d68b5d7..fbb9d611cf 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationWithExternalServiceProvider.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationWithExternalServiceProvider.cs @@ -1,4 +1,5 @@ using System; +using System.Threading.Tasks; using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection; @@ -35,6 +36,15 @@ internal class AbpApplicationWithExternalServiceProvider : AbpApplicationBase, I SetServiceProvider(serviceProvider); } + public async Task InitializeAsync(IServiceProvider serviceProvider) + { + Check.NotNull(serviceProvider, nameof(serviceProvider)); + + SetServiceProvider(serviceProvider); + + await InitializeModulesAsync(); + } + public void Initialize([NotNull] IServiceProvider serviceProvider) { Check.NotNull(serviceProvider, nameof(serviceProvider)); diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationWithInternalServiceProvider.cs b/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationWithInternalServiceProvider.cs index eb118410cd..245ce6fb06 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationWithInternalServiceProvider.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationWithInternalServiceProvider.cs @@ -1,4 +1,5 @@ using System; +using System.Threading.Tasks; using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection; @@ -44,6 +45,12 @@ internal class AbpApplicationWithInternalServiceProvider : AbpApplicationBase, I return ServiceProvider; } + public async Task InitializeAsync() + { + CreateServiceProvider(); + await InitializeModulesAsync(); + } + public void Initialize() { CreateServiceProvider(); diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/IAbpApplication.cs b/framework/src/Volo.Abp.Core/Volo/Abp/IAbpApplication.cs index de9201bebc..2fb66b735f 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/IAbpApplication.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/IAbpApplication.cs @@ -1,4 +1,5 @@ using System; +using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Modularity; @@ -22,6 +23,18 @@ public interface IAbpApplication : IModuleContainer, IDisposable /// This can not be used before initialize the application. /// IServiceProvider ServiceProvider { get; } + + /// + /// Calls the Pre/Post/ConfigureServicesAsync methods of the modules. + /// If you use this method, you must have set the + /// option to true before. + /// + Task ConfigureServicesAsync(); + + /// + /// Used to gracefully shutdown the application and all modules. + /// + Task ShutdownAsync(); /// /// Used to gracefully shutdown the application and all modules. diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/IAbpApplicationWithExternalServiceProvider.cs b/framework/src/Volo.Abp.Core/Volo/Abp/IAbpApplicationWithExternalServiceProvider.cs index 91c95f4518..a17bb146e3 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/IAbpApplicationWithExternalServiceProvider.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/IAbpApplicationWithExternalServiceProvider.cs @@ -1,4 +1,5 @@ using System; +using System.Threading.Tasks; using JetBrains.Annotations; namespace Volo.Abp; @@ -9,6 +10,13 @@ public interface IAbpApplicationWithExternalServiceProvider : IAbpApplication /// Sets the service provider, but not initializes the modules. /// void SetServiceProvider([NotNull] IServiceProvider serviceProvider); + + /// + /// Sets the service provider and initializes all the modules. + /// If was called before, the same + /// instance should be passed to this method. + /// + Task InitializeAsync([NotNull] IServiceProvider serviceProvider); /// /// Sets the service provider and initializes all the modules. diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/IAbpApplicationWithInternalServiceProvider.cs b/framework/src/Volo.Abp.Core/Volo/Abp/IAbpApplicationWithInternalServiceProvider.cs index 61fdb0652f..0079608c2e 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/IAbpApplicationWithInternalServiceProvider.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/IAbpApplicationWithInternalServiceProvider.cs @@ -1,4 +1,5 @@ using System; +using System.Threading.Tasks; namespace Volo.Abp; @@ -10,6 +11,13 @@ public interface IAbpApplicationWithInternalServiceProvider : IAbpApplication /// IServiceProvider CreateServiceProvider(); + /// + /// Creates the service provider and initializes all the modules. + /// If method was called before, + /// it does not re-create it, but uses the previous one. + /// + Task InitializeAsync(); + /// /// Creates the service provider and initializes all the modules. /// If method was called before, diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/IOnApplicationInitialization.cs b/framework/src/Volo.Abp.Core/Volo/Abp/IOnApplicationInitialization.cs index 5ed95a545b..6131a8b710 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/IOnApplicationInitialization.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/IOnApplicationInitialization.cs @@ -1,8 +1,11 @@ -using JetBrains.Annotations; +using System.Threading.Tasks; +using JetBrains.Annotations; namespace Volo.Abp; public interface IOnApplicationInitialization { + Task OnApplicationInitializationAsync([NotNull] ApplicationInitializationContext context); + void OnApplicationInitialization([NotNull] ApplicationInitializationContext context); } diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/IOnApplicationShutdown.cs b/framework/src/Volo.Abp.Core/Volo/Abp/IOnApplicationShutdown.cs index ced040851e..9f67ebb466 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/IOnApplicationShutdown.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/IOnApplicationShutdown.cs @@ -1,8 +1,11 @@ -using JetBrains.Annotations; +using System.Threading.Tasks; +using JetBrains.Annotations; namespace Volo.Abp; public interface IOnApplicationShutdown { + Task OnApplicationShutdownAsync([NotNull] ApplicationShutdownContext context); + void OnApplicationShutdown([NotNull] ApplicationShutdownContext context); } diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/AbpModule.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/AbpModule.cs index 537ccc54f6..ae2bec3112 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/AbpModule.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/AbpModule.cs @@ -1,5 +1,6 @@ using System; using System.Reflection; +using System.Threading.Tasks; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -30,36 +31,78 @@ public abstract class AbpModule : private ServiceConfigurationContext _serviceConfigurationContext; + public virtual Task PreConfigureServicesAsync(ServiceConfigurationContext context) + { + PreConfigureServices(context); + return Task.CompletedTask; + } + public virtual void PreConfigureServices(ServiceConfigurationContext context) { } + public virtual Task ConfigureServicesAsync(ServiceConfigurationContext context) + { + ConfigureServices(context); + return Task.CompletedTask; + } + public virtual void ConfigureServices(ServiceConfigurationContext context) { } + public virtual Task PostConfigureServicesAsync(ServiceConfigurationContext context) + { + PostConfigureServices(context); + return Task.CompletedTask; + } + public virtual void PostConfigureServices(ServiceConfigurationContext context) { } + public virtual Task OnPreApplicationInitializationAsync(ApplicationInitializationContext context) + { + OnPreApplicationInitialization(context); + return Task.CompletedTask; + } + public virtual void OnPreApplicationInitialization(ApplicationInitializationContext context) { } + public virtual Task OnApplicationInitializationAsync(ApplicationInitializationContext context) + { + OnApplicationInitialization(context); + return Task.CompletedTask; + } + public virtual void OnApplicationInitialization(ApplicationInitializationContext context) { } + public virtual Task OnPostApplicationInitializationAsync(ApplicationInitializationContext context) + { + OnPostApplicationInitialization(context); + return Task.CompletedTask; + } + public virtual void OnPostApplicationInitialization(ApplicationInitializationContext context) { } + public virtual Task OnApplicationShutdownAsync(ApplicationShutdownContext context) + { + OnApplicationShutdown(context); + return Task.CompletedTask; + } + public virtual void OnApplicationShutdown(ApplicationShutdownContext context) { diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/DefaultModuleLifecycleContributor.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/DefaultModuleLifecycleContributor.cs index f548cfaafb..c520cc8d58 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/DefaultModuleLifecycleContributor.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/DefaultModuleLifecycleContributor.cs @@ -1,7 +1,17 @@ -namespace Volo.Abp.Modularity; +using System.Threading.Tasks; + +namespace Volo.Abp.Modularity; public class OnApplicationInitializationModuleLifecycleContributor : ModuleLifecycleContributorBase { + public async override Task InitializeAsync(ApplicationInitializationContext context, IAbpModule module) + { + if (module is IOnApplicationInitialization onApplicationInitialization) + { + await onApplicationInitialization.OnApplicationInitializationAsync(context); + } + } + public override void Initialize(ApplicationInitializationContext context, IAbpModule module) { (module as IOnApplicationInitialization)?.OnApplicationInitialization(context); @@ -10,6 +20,14 @@ public class OnApplicationInitializationModuleLifecycleContributor : ModuleLifec public class OnApplicationShutdownModuleLifecycleContributor : ModuleLifecycleContributorBase { + public async override Task ShutdownAsync(ApplicationShutdownContext context, IAbpModule module) + { + if (module is IOnApplicationShutdown onApplicationShutdown) + { + await onApplicationShutdown.OnApplicationShutdownAsync(context); + } + } + public override void Shutdown(ApplicationShutdownContext context, IAbpModule module) { (module as IOnApplicationShutdown)?.OnApplicationShutdown(context); @@ -18,6 +36,14 @@ public class OnApplicationShutdownModuleLifecycleContributor : ModuleLifecycleCo public class OnPreApplicationInitializationModuleLifecycleContributor : ModuleLifecycleContributorBase { + public async override Task InitializeAsync(ApplicationInitializationContext context, IAbpModule module) + { + if (module is IOnPreApplicationInitialization onPreApplicationInitialization) + { + await onPreApplicationInitialization.OnPreApplicationInitializationAsync(context); + } + } + public override void Initialize(ApplicationInitializationContext context, IAbpModule module) { (module as IOnPreApplicationInitialization)?.OnPreApplicationInitialization(context); @@ -26,6 +52,14 @@ public class OnPreApplicationInitializationModuleLifecycleContributor : ModuleLi public class OnPostApplicationInitializationModuleLifecycleContributor : ModuleLifecycleContributorBase { + public async override Task InitializeAsync(ApplicationInitializationContext context, IAbpModule module) + { + if (module is IOnPostApplicationInitialization onPostApplicationInitialization) + { + await onPostApplicationInitialization.OnPostApplicationInitializationAsync(context); + } + } + public override void Initialize(ApplicationInitializationContext context, IAbpModule module) { (module as IOnPostApplicationInitialization)?.OnPostApplicationInitialization(context); diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/IAbpModule.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/IAbpModule.cs index b992020d4c..3622a50324 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/IAbpModule.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/IAbpModule.cs @@ -1,6 +1,10 @@ -namespace Volo.Abp.Modularity; +using System.Threading.Tasks; + +namespace Volo.Abp.Modularity; public interface IAbpModule { + Task ConfigureServicesAsync(ServiceConfigurationContext context); + void ConfigureServices(ServiceConfigurationContext context); } diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/IModuleLifecycleContributor.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/IModuleLifecycleContributor.cs index 299bfe9e5a..ca0ad1cfd8 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/IModuleLifecycleContributor.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/IModuleLifecycleContributor.cs @@ -1,11 +1,16 @@ -using JetBrains.Annotations; +using System.Threading.Tasks; +using JetBrains.Annotations; using Volo.Abp.DependencyInjection; namespace Volo.Abp.Modularity; public interface IModuleLifecycleContributor : ITransientDependency { + Task InitializeAsync([NotNull] ApplicationInitializationContext context, [NotNull] IAbpModule module); + void Initialize([NotNull] ApplicationInitializationContext context, [NotNull] IAbpModule module); + Task ShutdownAsync([NotNull] ApplicationShutdownContext context, [NotNull] IAbpModule module); + void Shutdown([NotNull] ApplicationShutdownContext context, [NotNull] IAbpModule module); } diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/IModuleManager.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/IModuleManager.cs index d981b745b9..eb4cf52e3c 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/IModuleManager.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/IModuleManager.cs @@ -1,10 +1,15 @@ -using JetBrains.Annotations; +using System.Threading.Tasks; +using JetBrains.Annotations; namespace Volo.Abp.Modularity; public interface IModuleManager { + Task InitializeModulesAsync([NotNull] ApplicationInitializationContext context); + void InitializeModules([NotNull] ApplicationInitializationContext context); + Task ShutdownModulesAsync([NotNull] ApplicationShutdownContext context); + void ShutdownModules([NotNull] ApplicationShutdownContext context); } diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/IOnPostApplicationInitialization.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/IOnPostApplicationInitialization.cs index d79a0318ec..26177360f9 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/IOnPostApplicationInitialization.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/IOnPostApplicationInitialization.cs @@ -1,8 +1,11 @@ -using JetBrains.Annotations; +using System.Threading.Tasks; +using JetBrains.Annotations; namespace Volo.Abp.Modularity; public interface IOnPostApplicationInitialization { + Task OnPostApplicationInitializationAsync([NotNull] ApplicationInitializationContext context); + void OnPostApplicationInitialization([NotNull] ApplicationInitializationContext context); } diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/IOnPreApplicationInitialization.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/IOnPreApplicationInitialization.cs index 0426ef50af..7e63301e3e 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/IOnPreApplicationInitialization.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/IOnPreApplicationInitialization.cs @@ -1,8 +1,11 @@ -using JetBrains.Annotations; +using System.Threading.Tasks; +using JetBrains.Annotations; namespace Volo.Abp.Modularity; public interface IOnPreApplicationInitialization { + Task OnPreApplicationInitializationAsync([NotNull] ApplicationInitializationContext context); + void OnPreApplicationInitialization([NotNull] ApplicationInitializationContext context); } diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/IPostConfigureServices.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/IPostConfigureServices.cs index 38d3449b85..a1ea07de27 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/IPostConfigureServices.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/IPostConfigureServices.cs @@ -1,8 +1,10 @@ -using Microsoft.Extensions.DependencyInjection; +using System.Threading.Tasks; namespace Volo.Abp.Modularity; public interface IPostConfigureServices { + Task PostConfigureServicesAsync(ServiceConfigurationContext context); + void PostConfigureServices(ServiceConfigurationContext context); } diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/IPreConfigureServices.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/IPreConfigureServices.cs index 51db8f5fb8..dfb9eef1df 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/IPreConfigureServices.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/IPreConfigureServices.cs @@ -1,8 +1,10 @@ -using Microsoft.Extensions.DependencyInjection; +using System.Threading.Tasks; namespace Volo.Abp.Modularity; public interface IPreConfigureServices { + Task PreConfigureServicesAsync(ServiceConfigurationContext context); + void PreConfigureServices(ServiceConfigurationContext context); } diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/ModuleLifecycleContributorBase.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/ModuleLifecycleContributorBase.cs index b3ac566eab..3192d1f2ea 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/ModuleLifecycleContributorBase.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/ModuleLifecycleContributorBase.cs @@ -1,11 +1,23 @@ -namespace Volo.Abp.Modularity; +using System.Threading.Tasks; + +namespace Volo.Abp.Modularity; public abstract class ModuleLifecycleContributorBase : IModuleLifecycleContributor { + public virtual Task InitializeAsync(ApplicationInitializationContext context, IAbpModule module) + { + return Task.CompletedTask; + } + public virtual void Initialize(ApplicationInitializationContext context, IAbpModule module) { } + public virtual Task ShutdownAsync(ApplicationShutdownContext context, IAbpModule module) + { + return Task.CompletedTask; + } + public virtual void Shutdown(ApplicationShutdownContext context, IAbpModule module) { } diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/ModuleManager.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/ModuleManager.cs index 2218b2f6fd..71697a1a83 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/ModuleManager.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/ModuleManager.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; @@ -30,6 +31,26 @@ public class ModuleManager : IModuleManager, ISingletonDependency .ToArray(); } + public virtual async Task InitializeModulesAsync(ApplicationInitializationContext context) + { + foreach (var contributor in _lifecycleContributors) + { + foreach (var module in _moduleContainer.Modules) + { + try + { + await contributor.InitializeAsync(context, module.Instance); + } + catch (Exception ex) + { + throw new AbpInitializationException($"An error occurred during the initialize {contributor.GetType().FullName} phase of the module {module.Type.AssemblyQualifiedName}: {ex.Message}. See the inner exception for details.", ex); + } + } + } + + _logger.LogInformation("Initialized all ABP modules."); + } + public void InitializeModules(ApplicationInitializationContext context) { foreach (var contributor in _lifecycleContributors) @@ -50,6 +71,26 @@ public class ModuleManager : IModuleManager, ISingletonDependency _logger.LogInformation("Initialized all ABP modules."); } + public virtual async Task ShutdownModulesAsync(ApplicationShutdownContext context) + { + var modules = _moduleContainer.Modules.Reverse().ToList(); + + foreach (var contributor in _lifecycleContributors) + { + foreach (var module in modules) + { + try + { + await contributor.ShutdownAsync(context, module.Instance); + } + catch (Exception ex) + { + throw new AbpShutdownException($"An error occurred during the shutdown {contributor.GetType().FullName} phase of the module {module.Type.AssemblyQualifiedName}: {ex.Message}. See the inner exception for details.", ex); + } + } + } + } + public void ShutdownModules(ApplicationShutdownContext context) { var modules = _moduleContainer.Modules.Reverse().ToList(); diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/AbpEventBusModule.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/AbpEventBusModule.cs index cb0a32f47c..b4a873dcd4 100644 --- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/AbpEventBusModule.cs +++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/AbpEventBusModule.cs @@ -1,6 +1,7 @@ using Microsoft.Extensions.DependencyInjection; using System; using System.Collections.Generic; +using System.Threading.Tasks; using Volo.Abp.BackgroundWorkers; using Volo.Abp.DistributedLocking; using Volo.Abp.EventBus.Abstractions; @@ -12,6 +13,7 @@ using Volo.Abp.Json; using Volo.Abp.Modularity; using Volo.Abp.MultiTenancy; using Volo.Abp.Reflection; +using Volo.Abp.Threading; namespace Volo.Abp.EventBus; @@ -30,10 +32,16 @@ public class AbpEventBusModule : AbpModule AddEventHandlers(context.Services); } + public async override Task OnApplicationInitializationAsync(ApplicationInitializationContext context) + { + await context.AddBackgroundWorkerAsync(); + await context.AddBackgroundWorkerAsync(); + } + public override void OnApplicationInitialization(ApplicationInitializationContext context) { - context.AddBackgroundWorker(); - context.AddBackgroundWorker(); + AsyncHelper.RunSync(() => context.AddBackgroundWorkerAsync()); + AsyncHelper.RunSync(() => context.AddBackgroundWorkerAsync()); } private static void AddEventHandlers(IServiceCollection services) diff --git a/framework/src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzModule.cs b/framework/src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzModule.cs index ade14f1b83..db790a717d 100644 --- a/framework/src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzModule.cs +++ b/framework/src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzModule.cs @@ -1,8 +1,8 @@ -using Microsoft.Extensions.DependencyInjection; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Quartz; using Quartz.Impl; -using Quartz.Impl.AdoJobStore.Common; using Volo.Abp.Modularity; using Volo.Abp.Threading; @@ -18,8 +18,8 @@ public class AbpQuartzModule : AbpModule context.Services.AddQuartz(options.Properties, build => { - // these are the defaults - if (options.Properties[StdSchedulerFactory.PropertySchedulerJobFactoryType] == null) + // these are the defaults + if (options.Properties[StdSchedulerFactory.PropertySchedulerJobFactoryType] == null) { build.UseMicrosoftDependencyInjectionScopedJobFactory(); } @@ -62,6 +62,23 @@ public class AbpQuartzModule : AbpModule }); } + public async override Task OnApplicationInitializationAsync(ApplicationInitializationContext context) + { + var options = context.ServiceProvider.GetRequiredService>().Value; + + _scheduler = context.ServiceProvider.GetRequiredService(); + + await options.StartSchedulerFactory.Invoke(_scheduler); + } + + public async override Task OnApplicationShutdownAsync(ApplicationShutdownContext context) + { + if (_scheduler.IsStarted) + { + await _scheduler.Shutdown(); + } + } + public override void OnApplicationInitialization(ApplicationInitializationContext context) { var options = context.ServiceProvider.GetRequiredService>().Value; diff --git a/framework/src/Volo.Abp.TestBase/Volo/Abp/AbpTestBaseWithServiceProvider.cs b/framework/src/Volo.Abp.TestBase/Volo/Abp/AbpTestBaseWithServiceProvider.cs index 6167d823cb..407660e854 100644 --- a/framework/src/Volo.Abp.TestBase/Volo/Abp/AbpTestBaseWithServiceProvider.cs +++ b/framework/src/Volo.Abp.TestBase/Volo/Abp/AbpTestBaseWithServiceProvider.cs @@ -5,7 +5,7 @@ namespace Volo.Abp; public abstract class AbpTestBaseWithServiceProvider { - protected abstract IServiceProvider ServiceProvider { get; } + protected IServiceProvider ServiceProvider { get; set; } protected virtual T GetService() { diff --git a/framework/src/Volo.Abp.TestBase/Volo/Abp/Testing/AbpAsyncIntegratedTest.cs b/framework/src/Volo.Abp.TestBase/Volo/Abp/Testing/AbpAsyncIntegratedTest.cs new file mode 100644 index 0000000000..4238a8712b --- /dev/null +++ b/framework/src/Volo.Abp.TestBase/Volo/Abp/Testing/AbpAsyncIntegratedTest.cs @@ -0,0 +1,70 @@ +using System; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Modularity; + +namespace Volo.Abp.Testing; + +public class AbpAsyncIntegratedTest : AbpTestBaseWithServiceProvider + where TStartupModule : IAbpModule +{ + protected IAbpApplication Application { get; set; } + + protected IServiceProvider RootServiceProvider { get; set; } + + protected IServiceScope TestServiceScope { get; set; } + + public virtual async Task InitializeAsync() + { + var services = await CreateServiceCollectionAsync(); + + await BeforeAddApplicationAsync(services); + var application = await services.AddApplicationAsync(await SetAbpApplicationCreationOptionsAsync()); + await AfterAddApplicationAsync(services); + + RootServiceProvider = await CreateServiceProviderAsync(services); + TestServiceScope = RootServiceProvider.CreateScope(); + await application.InitializeAsync(TestServiceScope.ServiceProvider); + ServiceProvider = application.ServiceProvider; + Application = application; + + await InitializeServicesAsync(); + } + + public virtual async Task DisposeAsync() + { + await Application.ShutdownAsync(); + TestServiceScope.Dispose(); + Application.Dispose(); + } + + protected virtual Task CreateServiceCollectionAsync() + { + return Task.FromResult(new ServiceCollection()); + } + + protected virtual Task BeforeAddApplicationAsync(IServiceCollection services) + { + return Task.CompletedTask; + } + + protected virtual Task> SetAbpApplicationCreationOptionsAsync() + { + return Task.FromResult>(_ => { }); + } + + protected virtual Task AfterAddApplicationAsync(IServiceCollection services) + { + return Task.CompletedTask; + } + + protected virtual Task CreateServiceProviderAsync(IServiceCollection services) + { + return Task.FromResult(services.BuildServiceProviderFromFactory()); + } + + protected virtual Task InitializeServicesAsync() + { + return Task.CompletedTask; + } +} diff --git a/framework/src/Volo.Abp.TestBase/Volo/Abp/Testing/AbpIntegratedTest.cs b/framework/src/Volo.Abp.TestBase/Volo/Abp/Testing/AbpIntegratedTest.cs index bb085f6f74..8d8612c5b9 100644 --- a/framework/src/Volo.Abp.TestBase/Volo/Abp/Testing/AbpIntegratedTest.cs +++ b/framework/src/Volo.Abp.TestBase/Volo/Abp/Testing/AbpIntegratedTest.cs @@ -9,8 +9,6 @@ public abstract class AbpIntegratedTest : AbpTestBaseWithService { protected IAbpApplication Application { get; } - protected override IServiceProvider ServiceProvider => Application.ServiceProvider; - protected IServiceProvider RootServiceProvider { get; } protected IServiceScope TestServiceScope { get; } @@ -30,6 +28,7 @@ public abstract class AbpIntegratedTest : AbpTestBaseWithService TestServiceScope = RootServiceProvider.CreateScope(); application.Initialize(TestServiceScope.ServiceProvider); + ServiceProvider = Application.ServiceProvider; } protected virtual IServiceCollection CreateServiceCollection() diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreAsyncTestBase_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreAsyncTestBase_Tests.cs new file mode 100644 index 0000000000..5d475966a2 --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreAsyncTestBase_Tests.cs @@ -0,0 +1,62 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; +using Shouldly; +using Volo.Abp.AspNetCore.TestBase; +using Volo.Abp.Autofac; +using Volo.Abp.Modularity; +using Xunit; + +namespace Volo.Abp.AspNetCore.Mvc; + +public class AbpAspNetCoreAsyncTestBase_Tests : AbpAspNetCoreAsyncTestBase +{ + [Fact] + public async Task Get_API_Response_Test() + { + var result = await GetResponseAsStringAsync("/api"); + result.ShouldBe(await GetRequiredService().GetResponseAsync()); + } +} + +[DependsOn( + typeof(AbpAspNetCoreMvcModule), + typeof(AbpAspNetCoreTestBaseModule), + typeof(AbpAutofacModule) +)] +public class AbpAspNetCoreAsyncTestModule : AbpModule +{ + public override Task ConfigureServicesAsync(ServiceConfigurationContext context) + { + context.Services.AddTransient(); + return Task.CompletedTask; + } + + public async override Task OnApplicationInitializationAsync(ApplicationInitializationContext context) + { + var app = context.GetApplicationBuilder(); + + var dataBaseService = app.ApplicationServices.GetRequiredService(); + + var apiResponse = await dataBaseService.GetResponseAsync(); + app.Map("/api", _ => + { + app.Run(async httpContext => + { + await httpContext.Response.WriteAsync(apiResponse); + }); + }); + + app.UseRouting(); + app.UseConfiguredEndpoints(); + } +} + +public class DataBaseService +{ + public Task GetResponseAsync() + { + return Task.FromResult("hello api!"); + } +} diff --git a/framework/test/Volo.Abp.AspNetCore.Tests/Volo/Abp/AspNetCore/AbpAspNetCoreAsyncTestBase.cs b/framework/test/Volo.Abp.AspNetCore.Tests/Volo/Abp/AspNetCore/AbpAspNetCoreAsyncTestBase.cs new file mode 100644 index 0000000000..0d222deab4 --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Tests/Volo/Abp/AspNetCore/AbpAspNetCoreAsyncTestBase.cs @@ -0,0 +1,45 @@ +using System.Globalization; +using System.Net; +using System.Net.Http; +using System.Text.Json; +using System.Threading.Tasks; +using Microsoft.Net.Http.Headers; +using Shouldly; +using Volo.Abp.AspNetCore.TestBase; +using Volo.Abp.Modularity; +using Xunit; + +namespace Volo.Abp.AspNetCore; + +public abstract class AbpAspNetCoreAsyncTestBase : AbpAspNetCoreAsyncIntegratedTestBase, IAsyncLifetime + where TModule : AbpModule +{ + protected virtual async Task GetResponseAsObjectAsync(string url, HttpStatusCode expectedStatusCode = HttpStatusCode.OK) + { + var strResponse = await GetResponseAsStringAsync(url, expectedStatusCode); + return JsonSerializer.Deserialize(strResponse, new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); + } + + protected virtual async Task GetResponseAsStringAsync(string url, HttpStatusCode expectedStatusCode = HttpStatusCode.OK) + { + using (var response = await GetResponseAsync(url, expectedStatusCode)) + { + return await response.Content.ReadAsStringAsync(); + } + } + + protected virtual async Task GetResponseAsync(string url, HttpStatusCode expectedStatusCode = HttpStatusCode.OK, bool xmlHttpRequest = false) + { + using (var requestMessage = new HttpRequestMessage(HttpMethod.Get, url)) + { + requestMessage.Headers.Add("Accept-Language", CultureInfo.CurrentUICulture.Name); + if (xmlHttpRequest) + { + requestMessage.Headers.Add(HeaderNames.XRequestedWith, "XMLHttpRequest"); + } + var response = await Client.SendAsync(requestMessage); + response.StatusCode.ShouldBe(expectedStatusCode); + return response; + } + } +} diff --git a/framework/test/Volo.Abp.Autofac.Tests/Volo/Abp/Autofac/Interception/Autofac_Interception_Test.cs b/framework/test/Volo.Abp.Autofac.Tests/Volo/Abp/Autofac/Interception/Autofac_Interception_Test.cs index a7a2dfafbc..290abda61b 100644 --- a/framework/test/Volo.Abp.Autofac.Tests/Volo/Abp/Autofac/Interception/Autofac_Interception_Test.cs +++ b/framework/test/Volo.Abp.Autofac.Tests/Volo/Abp/Autofac/Interception/Autofac_Interception_Test.cs @@ -1,11 +1,13 @@ -using Volo.Abp.DynamicProxy; +using System; +using System.Threading.Tasks; +using Volo.Abp.DynamicProxy; namespace Volo.Abp.Autofac.Interception; public class Autofac_Interception_Test : AbpInterceptionTestBase { - protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) + protected override Task> SetAbpApplicationCreationOptionsAsync() { - options.UseAutofac(); + return Task.FromResult>(options => options.UseAutofac()); } } diff --git a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/AbpApplication_Initialize_Tests.cs b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/AbpApplication_Initialize_Tests.cs index 63bc7f5f78..f69d94ce61 100644 --- a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/AbpApplication_Initialize_Tests.cs +++ b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/AbpApplication_Initialize_Tests.cs @@ -1,4 +1,5 @@ -using Microsoft.Extensions.DependencyInjection; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; using Shouldly; using Volo.Abp.Modularity; using Volo.Abp.Modularity.PlugIns; @@ -8,6 +9,39 @@ namespace Volo.Abp; public class AbpApplication_Initialize_Tests { + [Fact] + public async Task Should_Initialize_Single_Module_Async() + { + using (var application = await AbpApplicationFactory.CreateAsync()) + { + //Assert + var module = application.Services.GetSingletonInstance(); + + module.PreConfigureServicesAsyncIsCalled.ShouldBeTrue(); + module.PreConfigureServicesIsCalled.ShouldBeTrue(); + + module.ConfigureServicesAsyncIsCalled.ShouldBeTrue(); + module.ConfigureServicesIsCalled.ShouldBeTrue(); + + module.PostConfigureServicesAsyncIsCalled.ShouldBeTrue(); + module.PostConfigureServicesIsCalled.ShouldBeTrue(); + + //Act + await application.InitializeAsync(); + + //Assert + application.ServiceProvider.GetRequiredService().ShouldBeSameAs(module); + module.OnApplicationInitializeAsyncIsCalled.ShouldBeTrue(); + module.OnApplicationInitializeIsCalled.ShouldBeTrue(); + //Act + await application.ShutdownAsync(); + + //Assert + module.OnApplicationShutdownAsyncIsCalled.ShouldBeTrue(); + module.OnApplicationShutdownIsCalled.ShouldBeTrue(); + } + } + [Fact] public void Should_Initialize_Single_Module() { @@ -34,6 +68,50 @@ public class AbpApplication_Initialize_Tests } } + [Fact] + public async Task Should_Initialize_PlugIn_Async() + { + using (var application = await AbpApplicationFactory.CreateAsync(options => + { + options.PlugInSources.AddTypes(typeof(IndependentEmptyPlugInModule)); + })) + { + //Assert + var plugInModule = application.Services.GetSingletonInstance(); + + plugInModule.PreConfigureServicesAsyncIsCalled.ShouldBeTrue(); + plugInModule.PreConfigureServicesIsCalled.ShouldBeTrue(); + + plugInModule.ConfigureServicesAsyncIsCalled.ShouldBeTrue(); + plugInModule.ConfigureServicesIsCalled.ShouldBeTrue(); + + plugInModule.PostConfigureServicesAsyncIsCalled.ShouldBeTrue(); + plugInModule.PostConfigureServicesIsCalled.ShouldBeTrue(); + + //Act + await application.InitializeAsync(); + + //Assert + application.ServiceProvider.GetRequiredService().ShouldBeSameAs(plugInModule); + + plugInModule.OnPreApplicationInitializationAsyncIsCalled.ShouldBeTrue(); + plugInModule.OnPreApplicationInitializationIsCalled.ShouldBeTrue(); + + plugInModule.OnApplicationInitializeAsyncIsCalled.ShouldBeTrue(); + plugInModule.OnApplicationInitializeIsCalled.ShouldBeTrue(); + + plugInModule.OnPostApplicationInitializationAsyncIsCalled.ShouldBeTrue(); + plugInModule.OnPostApplicationInitializationIsCalled.ShouldBeTrue(); + + //Act + await application.ShutdownAsync(); + + //Assert + plugInModule.OnApplicationShutdownAsyncIsCalled.ShouldBeTrue(); + plugInModule.OnApplicationShutdownIsCalled.ShouldBeTrue(); + } + } + [Fact] public void Should_Initialize_PlugIn() { @@ -53,7 +131,9 @@ public class AbpApplication_Initialize_Tests //Assert application.ServiceProvider.GetRequiredService().ShouldBeSameAs(plugInModule); + plugInModule.OnPreApplicationInitializationIsCalled.ShouldBeTrue(); plugInModule.OnApplicationInitializeIsCalled.ShouldBeTrue(); + plugInModule.OnPostApplicationInitializationIsCalled.ShouldBeTrue(); //Act application.Shutdown(); diff --git a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/Configuration/ConfigurationAccessor_Tests.cs b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/Configuration/ConfigurationAccessor_Tests.cs index 9023fb6ce7..4a0dda26fb 100644 --- a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/Configuration/ConfigurationAccessor_Tests.cs +++ b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/Configuration/ConfigurationAccessor_Tests.cs @@ -1,4 +1,5 @@ -using Microsoft.Extensions.Configuration; +using System.Threading.Tasks; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Shouldly; using Volo.Abp.Modularity; @@ -8,6 +9,22 @@ namespace Volo.Abp.Configuration; public class ConfigurationAccessor_Tests { + [Fact] + public async Task Should_Use_Empty_ConfigurationRoot_By_Default_Async() + { + using (var application = await AbpApplicationFactory.CreateAsync()) + { + var configuration1 = application.Services.GetConfiguration(); + configuration1.ShouldNotBeNull(); + + await application.InitializeAsync(); + + var configuration2 = ResolveConfiguration(application); + + configuration2.ShouldBe(configuration1); + } + } + [Fact] public void Should_Use_Empty_ConfigurationRoot_By_Default() { @@ -24,6 +41,23 @@ public class ConfigurationAccessor_Tests } } + [Fact] + public async Task Should_Use_The_Registered_ConfigurationRoot_Async() + { + using (var application = await AbpApplicationFactory.CreateAsync()) + { + var myConfiguration = new ConfigurationBuilder().Build(); + application.Services.ReplaceConfiguration(myConfiguration); + application.Services.GetConfiguration().ShouldBe(myConfiguration); + + await application.InitializeAsync(); + + var configuration = ResolveConfiguration(application); + + configuration.ShouldBe(myConfiguration); + } + } + [Fact] public void Should_Use_The_Registered_ConfigurationRoot() { diff --git a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/DependencyInjection/AutoServiceRegistration_Tests.cs b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/DependencyInjection/AutoServiceRegistration_Tests.cs index 6fc5716a22..71ec559824 100644 --- a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/DependencyInjection/AutoServiceRegistration_Tests.cs +++ b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/DependencyInjection/AutoServiceRegistration_Tests.cs @@ -1,4 +1,5 @@ using System.Linq; +using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Shouldly; using Volo.Abp.Modularity; @@ -8,6 +9,20 @@ namespace Volo.Abp.DependencyInjection; public class AutoServiceRegistration_Tests { + [Fact] + public async Task AutoServiceRegistration_Should_Not_Duplicate_Test_Async() + { + using (var application = await AbpApplicationFactory.CreateAsync()) + { + //Act + await application.InitializeAsync(); + + //Assert + var services = application.ServiceProvider.GetServices().ToList(); + services.Count.ShouldBe(1); + } + } + [Fact] public void AutoServiceRegistration_Should_Not_Duplicate_Test() { diff --git a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/DependencyInjection/HybridServiceScopeFactory_Tests.cs b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/DependencyInjection/HybridServiceScopeFactory_Tests.cs index d665c863dc..6a3f059ba8 100644 --- a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/DependencyInjection/HybridServiceScopeFactory_Tests.cs +++ b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/DependencyInjection/HybridServiceScopeFactory_Tests.cs @@ -1,4 +1,5 @@ using System; +using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Shouldly; using Volo.Abp.Modularity; @@ -8,6 +9,26 @@ namespace Volo.Abp.DependencyInjection; public class HybridServiceScopeFactory_Tests { + [Fact] + public async Task Should_Use_Default_ServiceScopeFactory_By_Default_Async() + { + using (var application = await AbpApplicationFactory.CreateAsync()) + { + application.Services.AddType(typeof(MyServiceAsync)); + + await application.InitializeAsync(); + + var serviceScopeFactory = application.ServiceProvider.GetRequiredService(); + + using (var scope = serviceScopeFactory.CreateScope()) + { + scope.ServiceProvider.GetRequiredService(); + } + + MyServiceAsync.DisposeCount.ShouldBe(1); + } + } + [Fact] public void Should_Use_Default_ServiceScopeFactory_By_Default() { @@ -28,6 +49,16 @@ public class HybridServiceScopeFactory_Tests } } + private class MyServiceAsync : ITransientDependency, IDisposable + { + public static int DisposeCount { get; private set; } + + public void Dispose() + { + ++DisposeCount; + } + } + private class MyService : ITransientDependency, IDisposable { public static int DisposeCount { get; private set; } diff --git a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/DynamicProxy/AbpInterceptionTestBase.cs b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/DynamicProxy/AbpInterceptionTestBase.cs index befc9af679..f4b584701f 100644 --- a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/DynamicProxy/AbpInterceptionTestBase.cs +++ b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/DynamicProxy/AbpInterceptionTestBase.cs @@ -7,10 +7,10 @@ using Xunit; namespace Volo.Abp.DynamicProxy; -public abstract class AbpInterceptionTestBase : AbpIntegratedTest +public abstract class AbpInterceptionTestBase : AbpAsyncIntegratedTest, IAsyncLifetime where TStartupModule : IAbpModule { - protected override void BeforeAddApplication(IServiceCollection services) + protected override Task BeforeAddApplicationAsync(IServiceCollection services) { services.AddTransient(); services.AddTransient(); @@ -32,6 +32,8 @@ public abstract class AbpInterceptionTestBase : AbpIntegratedTes registration.Interceptors.Add(); } }); + + return Task.CompletedTask; } [Fact] diff --git a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/Modularity/TestModuleBase.cs b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/Modularity/TestModuleBase.cs index 327d2982a5..29b7927c64 100644 --- a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/Modularity/TestModuleBase.cs +++ b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/Modularity/TestModuleBase.cs @@ -1,39 +1,97 @@ -using Microsoft.Extensions.DependencyInjection; +using System.Threading.Tasks; namespace Volo.Abp.Modularity; public class TestModuleBase : AbpModule { - public bool PreConfigureServicesIsCalled { get; set; } + public bool PreConfigureServicesAsyncIsCalled { get; set; } + public bool ConfigureServicesAsyncIsCalled { get; set; } + public bool PostConfigureServicesAsyncIsCalled { get; set; } + public bool OnPreApplicationInitializationIsCalled { get; set; } + public bool OnPostApplicationInitializationIsCalled { get; set; } + public bool OnApplicationInitializeAsyncIsCalled { get; set; } + public bool OnApplicationShutdownAsyncIsCalled { get; set; } + public bool PreConfigureServicesIsCalled { get; set; } public bool ConfigureServicesIsCalled { get; set; } - public bool PostConfigureServicesIsCalled { get; set; } - + public bool OnPreApplicationInitializationAsyncIsCalled { get; set; } + public bool OnPostApplicationInitializationAsyncIsCalled { get; set; } public bool OnApplicationInitializeIsCalled { get; set; } - public bool OnApplicationShutdownIsCalled { get; set; } + public override Task PreConfigureServicesAsync(ServiceConfigurationContext context) + { + PreConfigureServicesAsyncIsCalled = true; + return base.PreConfigureServicesAsync(context); + } + public override void PreConfigureServices(ServiceConfigurationContext context) { PreConfigureServicesIsCalled = true; } + public override Task ConfigureServicesAsync(ServiceConfigurationContext context) + { + ConfigureServicesAsyncIsCalled = true; + return base.ConfigureServicesAsync(context); + } + public override void ConfigureServices(ServiceConfigurationContext context) { ConfigureServicesIsCalled = true; } + public override Task PostConfigureServicesAsync(ServiceConfigurationContext context) + { + PostConfigureServicesAsyncIsCalled = true; + return base.PostConfigureServicesAsync(context); + } + public override void PostConfigureServices(ServiceConfigurationContext context) { PostConfigureServicesIsCalled = true; } + public override Task OnPreApplicationInitializationAsync(ApplicationInitializationContext context) + { + OnPreApplicationInitializationAsyncIsCalled = true; + return base.OnPreApplicationInitializationAsync(context); + } + + public override void OnPreApplicationInitialization(ApplicationInitializationContext context) + { + OnPreApplicationInitializationIsCalled = true; + } + + public override Task OnPostApplicationInitializationAsync(ApplicationInitializationContext context) + { + OnPostApplicationInitializationAsyncIsCalled = true; + return base.OnPostApplicationInitializationAsync(context); + } + + public override void OnPostApplicationInitialization(ApplicationInitializationContext context) + { + OnPostApplicationInitializationIsCalled = true; + } + + public override Task OnApplicationInitializationAsync(ApplicationInitializationContext context) + { + OnApplicationInitializeAsyncIsCalled = true; + return base.OnApplicationInitializationAsync(context); + } + public override void OnApplicationInitialization(ApplicationInitializationContext context) { OnApplicationInitializeIsCalled = true; } + public override Task OnApplicationShutdownAsync(ApplicationShutdownContext context) + { + OnApplicationShutdownAsyncIsCalled = true; + return base.OnApplicationShutdownAsync(context); + } + public override void OnApplicationShutdown(ApplicationShutdownContext context) { OnApplicationShutdownIsCalled = true; diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/DocsDomainModule.cs b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/DocsDomainModule.cs index ecc52d1f26..d6c7a3a0a6 100644 --- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/DocsDomainModule.cs +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/DocsDomainModule.cs @@ -1,4 +1,5 @@ using System; +using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Volo.Abp; @@ -39,7 +40,7 @@ namespace Volo.Docs options.EtoMappings.Add(typeof(DocsDomainModule)); options.EtoMappings.Add(typeof(DocsDomainModule)); }); - + Configure(options => { options.FileSets @@ -65,6 +66,18 @@ namespace Volo.Docs }); } + public async override Task OnApplicationInitializationAsync(ApplicationInitializationContext context) + { + using (var scope = context.ServiceProvider.CreateScope()) + { + if (scope.ServiceProvider.GetRequiredService>().Value.Enable) + { + var documentFullSearch = scope.ServiceProvider.GetRequiredService(); + await documentFullSearch.CreateIndexIfNeededAsync(); + } + } + } + public override void OnApplicationInitialization(ApplicationInitializationContext context) { using (var scope = context.ServiceProvider.CreateScope()) diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpIdentityServerDomainModule.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpIdentityServerDomainModule.cs index d3663277cb..1f8fb93e4b 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpIdentityServerDomainModule.cs +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpIdentityServerDomainModule.cs @@ -1,4 +1,5 @@ -using IdentityServer4.Services; +using System.Threading.Tasks; +using IdentityServer4.Services; using IdentityServer4.Stores; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; @@ -133,17 +134,31 @@ public class AbpIdentityServerDomainModule : AbpModule }); } - public override void OnApplicationInitialization(ApplicationInitializationContext context) + public async override Task OnApplicationInitializationAsync(ApplicationInitializationContext context) { var options = context.ServiceProvider.GetRequiredService>().Value; if (options.IsCleanupEnabled) { - context.ServiceProvider + await context.ServiceProvider .GetRequiredService() - .Add( + .AddAsync( context.ServiceProvider .GetRequiredService() ); } } + + public override void OnApplicationInitialization(ApplicationInitializationContext context) + { + var options = context.ServiceProvider.GetRequiredService>().Value; + if (options.IsCleanupEnabled) + { + AsyncHelper.RunSync(() => context.ServiceProvider + .GetRequiredService() + .AddAsync( + context.ServiceProvider + .GetRequiredService() + )); + } + } } diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/Program.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/Program.cs index c783074558..838c64e004 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/Program.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/Program.cs @@ -1,6 +1,7 @@ using System; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Serilog; using Serilog.Events; @@ -9,27 +10,37 @@ namespace MyCompanyName.MyProjectName.Blazor.Server.Tiered; public class Program { - public static int Main(string[] args) + public async static Task Main(string[] args) { Log.Logger = new LoggerConfiguration() #if DEBUG - .MinimumLevel.Debug() + .MinimumLevel.Debug() #else - .MinimumLevel.Information() + .MinimumLevel.Information() #endif - .MinimumLevel.Override("Microsoft", LogEventLevel.Information) + .MinimumLevel.Override("Microsoft", LogEventLevel.Information) .MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning) .Enrich.FromLogContext() .WriteTo.Async(c => c.File("Logs/logs.txt")) #if DEBUG - .WriteTo.Async(c => c.Console()) + .WriteTo.Async(c => c.Console()) #endif - .CreateLogger(); + .CreateLogger(); try { Log.Information("Starting web host."); - CreateHostBuilder(args).Build().Run(); + var builder = WebApplication.CreateBuilder(args); + builder.Host.AddAppSettingsSecretsJson() + .UseAutofac() + .UseSerilog(); + await builder.Services.AddApplicationAsync(options => + { + options.Services.ReplaceConfiguration(builder.Configuration); + }); + var app = builder.Build(); + await app.InitializeApplicationAsync(); + await app.RunAsync(); return 0; } catch (Exception ex) @@ -42,14 +53,4 @@ public class Program Log.CloseAndFlush(); } } - - public static IHostBuilder CreateHostBuilder(string[] args) => - Host.CreateDefaultBuilder(args) - .AddAppSettingsSecretsJson() - .ConfigureWebHostDefaults(webBuilder => - { - webBuilder.UseStartup(); - }) - .UseAutofac() - .UseSerilog(); } diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/Startup.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/Startup.cs deleted file mode 100644 index d3aed6dfd0..0000000000 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/Startup.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.DependencyInjection; - -namespace MyCompanyName.MyProjectName.Blazor.Server.Tiered; - -public class Startup -{ - public void ConfigureServices(IServiceCollection services) - { - services.AddApplication(); - } - - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) - { - app.InitializeApplication(); - } -} diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/Program.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/Program.cs index d414fd7b78..b9aad1a4cd 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/Program.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/Program.cs @@ -1,6 +1,7 @@ using System; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Serilog; using Serilog.Events; @@ -9,27 +10,37 @@ namespace MyCompanyName.MyProjectName.Blazor.Server; public class Program { - public static int Main(string[] args) + public async static Task Main(string[] args) { Log.Logger = new LoggerConfiguration() #if DEBUG - .MinimumLevel.Debug() + .MinimumLevel.Debug() #else - .MinimumLevel.Information() + .MinimumLevel.Information() #endif - .MinimumLevel.Override("Microsoft", LogEventLevel.Information) + .MinimumLevel.Override("Microsoft", LogEventLevel.Information) .MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning) .Enrich.FromLogContext() .WriteTo.Async(c => c.File("Logs/logs.txt")) #if DEBUG - .WriteTo.Async(c => c.Console()) + .WriteTo.Async(c => c.Console()) #endif - .CreateLogger(); + .CreateLogger(); try { Log.Information("Starting web host."); - CreateHostBuilder(args).Build().Run(); + var builder = WebApplication.CreateBuilder(args); + builder.Host.AddAppSettingsSecretsJson() + .UseAutofac() + .UseSerilog(); + await builder.Services.AddApplicationAsync(options => + { + options.Services.ReplaceConfiguration(builder.Configuration); + }); + var app = builder.Build(); + await app.InitializeApplicationAsync(); + await app.RunAsync(); return 0; } catch (Exception ex) @@ -42,14 +53,4 @@ public class Program Log.CloseAndFlush(); } } - - public static IHostBuilder CreateHostBuilder(string[] args) => - Host.CreateDefaultBuilder(args) - .AddAppSettingsSecretsJson() - .ConfigureWebHostDefaults(webBuilder => - { - webBuilder.UseStartup(); - }) - .UseAutofac() - .UseSerilog(); } diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/Startup.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/Startup.cs deleted file mode 100644 index 1aae1bb1d3..0000000000 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/Startup.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.DependencyInjection; - -namespace MyCompanyName.MyProjectName.Blazor.Server; - -public class Startup -{ - public void ConfigureServices(IServiceCollection services) - { - services.AddApplication(); - } - - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) - { - app.InitializeApplication(); - } -} diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/Program.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/Program.cs index 1ded753836..027cac3dcf 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/Program.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/Program.cs @@ -5,11 +5,11 @@ namespace MyCompanyName.MyProjectName.Blazor; public class Program { - public static async Task Main(string[] args) + public async static Task Main(string[] args) { var builder = WebAssemblyHostBuilder.CreateDefault(args); - var application = builder.AddApplication(options => + var application = await builder.AddApplicationAsync(options => { options.UseAutofac(); }); diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/Program.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/Program.cs index fbbae26ddd..59b85f1a90 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/Program.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/Program.cs @@ -1,6 +1,7 @@ using System; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Serilog; using Serilog.Events; @@ -9,27 +10,37 @@ namespace MyCompanyName.MyProjectName; public class Program { - public static int Main(string[] args) + public async static Task Main(string[] args) { Log.Logger = new LoggerConfiguration() #if DEBUG - .MinimumLevel.Debug() + .MinimumLevel.Debug() #else - .MinimumLevel.Information() + .MinimumLevel.Information() #endif - .MinimumLevel.Override("Microsoft", LogEventLevel.Information) + .MinimumLevel.Override("Microsoft", LogEventLevel.Information) .MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning) .Enrich.FromLogContext() .WriteTo.Async(c => c.File("Logs/logs.txt")) #if DEBUG - .WriteTo.Async(c => c.Console()) + .WriteTo.Async(c => c.Console()) #endif - .CreateLogger(); + .CreateLogger(); try { Log.Information("Starting MyCompanyName.MyProjectName.HttpApi.Host."); - CreateHostBuilder(args).Build().Run(); + var builder = WebApplication.CreateBuilder(args); + builder.Host.AddAppSettingsSecretsJson() + .UseAutofac() + .UseSerilog(); + await builder.Services.AddApplicationAsync(options => + { + options.Services.ReplaceConfiguration(builder.Configuration); + }); + var app = builder.Build(); + await app.InitializeApplicationAsync(); + await app.RunAsync(); return 0; } catch (Exception ex) @@ -42,14 +53,4 @@ public class Program Log.CloseAndFlush(); } } - - internal static IHostBuilder CreateHostBuilder(string[] args) => - Host.CreateDefaultBuilder(args) - .AddAppSettingsSecretsJson() - .ConfigureWebHostDefaults(webBuilder => - { - webBuilder.UseStartup(); - }) - .UseAutofac() - .UseSerilog(); } diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/Startup.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/Startup.cs deleted file mode 100644 index 05e84529fc..0000000000 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/Startup.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; - -namespace MyCompanyName.MyProjectName; - -public class Startup -{ - public void ConfigureServices(IServiceCollection services) - { - services.AddApplication(); - } - - public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory) - { - app.InitializeApplication(); - } -} diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/Program.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/Program.cs index fbbae26ddd..59b85f1a90 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/Program.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/Program.cs @@ -1,6 +1,7 @@ using System; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Serilog; using Serilog.Events; @@ -9,27 +10,37 @@ namespace MyCompanyName.MyProjectName; public class Program { - public static int Main(string[] args) + public async static Task Main(string[] args) { Log.Logger = new LoggerConfiguration() #if DEBUG - .MinimumLevel.Debug() + .MinimumLevel.Debug() #else - .MinimumLevel.Information() + .MinimumLevel.Information() #endif - .MinimumLevel.Override("Microsoft", LogEventLevel.Information) + .MinimumLevel.Override("Microsoft", LogEventLevel.Information) .MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning) .Enrich.FromLogContext() .WriteTo.Async(c => c.File("Logs/logs.txt")) #if DEBUG - .WriteTo.Async(c => c.Console()) + .WriteTo.Async(c => c.Console()) #endif - .CreateLogger(); + .CreateLogger(); try { Log.Information("Starting MyCompanyName.MyProjectName.HttpApi.Host."); - CreateHostBuilder(args).Build().Run(); + var builder = WebApplication.CreateBuilder(args); + builder.Host.AddAppSettingsSecretsJson() + .UseAutofac() + .UseSerilog(); + await builder.Services.AddApplicationAsync(options => + { + options.Services.ReplaceConfiguration(builder.Configuration); + }); + var app = builder.Build(); + await app.InitializeApplicationAsync(); + await app.RunAsync(); return 0; } catch (Exception ex) @@ -42,14 +53,4 @@ public class Program Log.CloseAndFlush(); } } - - internal static IHostBuilder CreateHostBuilder(string[] args) => - Host.CreateDefaultBuilder(args) - .AddAppSettingsSecretsJson() - .ConfigureWebHostDefaults(webBuilder => - { - webBuilder.UseStartup(); - }) - .UseAutofac() - .UseSerilog(); } diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/Startup.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/Startup.cs deleted file mode 100644 index 05e84529fc..0000000000 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/Startup.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; - -namespace MyCompanyName.MyProjectName; - -public class Startup -{ - public void ConfigureServices(IServiceCollection services) - { - services.AddApplication(); - } - - public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory) - { - app.InitializeApplication(); - } -} diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/Program.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/Program.cs index c1592d400c..aca0769330 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/Program.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/Program.cs @@ -1,6 +1,7 @@ using System; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Serilog; using Serilog.Events; @@ -9,27 +10,37 @@ namespace MyCompanyName.MyProjectName; public class Program { - public static int Main(string[] args) + public async static Task Main(string[] args) { Log.Logger = new LoggerConfiguration() #if DEBUG - .MinimumLevel.Debug() + .MinimumLevel.Debug() #else - .MinimumLevel.Information() + .MinimumLevel.Information() #endif - .MinimumLevel.Override("Microsoft", LogEventLevel.Information) + .MinimumLevel.Override("Microsoft", LogEventLevel.Information) .MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning) .Enrich.FromLogContext() .WriteTo.Async(c => c.File("Logs/logs.txt")) #if DEBUG - .WriteTo.Async(c => c.Console()) + .WriteTo.Async(c => c.Console()) #endif - .CreateLogger(); + .CreateLogger(); try { Log.Information("Starting MyCompanyName.MyProjectName.IdentityServer."); - CreateHostBuilder(args).Build().Run(); + var builder = WebApplication.CreateBuilder(args); + builder.Host.AddAppSettingsSecretsJson() + .UseAutofac() + .UseSerilog(); + await builder.Services.AddApplicationAsync(options => + { + options.Services.ReplaceConfiguration(builder.Configuration); + }); + var app = builder.Build(); + await app.InitializeApplicationAsync(); + await app.RunAsync(); return 0; } catch (Exception ex) @@ -42,14 +53,4 @@ public class Program Log.CloseAndFlush(); } } - - internal static IHostBuilder CreateHostBuilder(string[] args) => - Host.CreateDefaultBuilder(args) - .AddAppSettingsSecretsJson() - .ConfigureWebHostDefaults(webBuilder => - { - webBuilder.UseStartup(); - }) - .UseAutofac() - .UseSerilog(); } diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/Startup.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/Startup.cs deleted file mode 100644 index 50f174aa59..0000000000 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/Startup.cs +++ /dev/null @@ -1,17 +0,0 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.Extensions.DependencyInjection; - -namespace MyCompanyName.MyProjectName; - -public class Startup -{ - public void ConfigureServices(IServiceCollection services) - { - services.AddApplication(); - } - - public void Configure(IApplicationBuilder app) - { - app.InitializeApplication(); - } -} diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/Program.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/Program.cs index fa6764a4fd..3cd8f691dc 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/Program.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/Program.cs @@ -1,6 +1,7 @@ using System; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Serilog; using Serilog.Events; @@ -9,27 +10,37 @@ namespace MyCompanyName.MyProjectName.Web; public class Program { - public static int Main(string[] args) + public async static Task Main(string[] args) { Log.Logger = new LoggerConfiguration() #if DEBUG - .MinimumLevel.Debug() + .MinimumLevel.Debug() #else - .MinimumLevel.Information() + .MinimumLevel.Information() #endif - .MinimumLevel.Override("Microsoft", LogEventLevel.Information) + .MinimumLevel.Override("Microsoft", LogEventLevel.Information) .MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning) .Enrich.FromLogContext() .WriteTo.Async(c => c.File("Logs/logs.txt")) #if DEBUG - .WriteTo.Async(c => c.Console()) + .WriteTo.Async(c => c.Console()) #endif - .CreateLogger(); + .CreateLogger(); try { Log.Information("Starting web host."); - CreateHostBuilder(args).Build().Run(); + var builder = WebApplication.CreateBuilder(args); + builder.Host.AddAppSettingsSecretsJson() + .UseAutofac() + .UseSerilog(); + await builder.Services.AddApplicationAsync(options => + { + options.Services.ReplaceConfiguration(builder.Configuration); + }); + var app = builder.Build(); + await app.InitializeApplicationAsync(); + await app.RunAsync(); return 0; } catch (Exception ex) @@ -42,14 +53,4 @@ public class Program Log.CloseAndFlush(); } } - - internal static IHostBuilder CreateHostBuilder(string[] args) => - Host.CreateDefaultBuilder(args) - .AddAppSettingsSecretsJson() - .ConfigureWebHostDefaults(webBuilder => - { - webBuilder.UseStartup(); - }) - .UseAutofac() - .UseSerilog(); } diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/Startup.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/Startup.cs deleted file mode 100644 index 8175f31cb7..0000000000 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/Startup.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; - -namespace MyCompanyName.MyProjectName.Web; - -public class Startup -{ - public void ConfigureServices(IServiceCollection services) - { - services.AddApplication(); - } - - public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory) - { - app.InitializeApplication(); - } -} diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/Program.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/Program.cs index fa6764a4fd..3cd8f691dc 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/Program.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/Program.cs @@ -1,6 +1,7 @@ using System; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Serilog; using Serilog.Events; @@ -9,27 +10,37 @@ namespace MyCompanyName.MyProjectName.Web; public class Program { - public static int Main(string[] args) + public async static Task Main(string[] args) { Log.Logger = new LoggerConfiguration() #if DEBUG - .MinimumLevel.Debug() + .MinimumLevel.Debug() #else - .MinimumLevel.Information() + .MinimumLevel.Information() #endif - .MinimumLevel.Override("Microsoft", LogEventLevel.Information) + .MinimumLevel.Override("Microsoft", LogEventLevel.Information) .MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning) .Enrich.FromLogContext() .WriteTo.Async(c => c.File("Logs/logs.txt")) #if DEBUG - .WriteTo.Async(c => c.Console()) + .WriteTo.Async(c => c.Console()) #endif - .CreateLogger(); + .CreateLogger(); try { Log.Information("Starting web host."); - CreateHostBuilder(args).Build().Run(); + var builder = WebApplication.CreateBuilder(args); + builder.Host.AddAppSettingsSecretsJson() + .UseAutofac() + .UseSerilog(); + await builder.Services.AddApplicationAsync(options => + { + options.Services.ReplaceConfiguration(builder.Configuration); + }); + var app = builder.Build(); + await app.InitializeApplicationAsync(); + await app.RunAsync(); return 0; } catch (Exception ex) @@ -42,14 +53,4 @@ public class Program Log.CloseAndFlush(); } } - - internal static IHostBuilder CreateHostBuilder(string[] args) => - Host.CreateDefaultBuilder(args) - .AddAppSettingsSecretsJson() - .ConfigureWebHostDefaults(webBuilder => - { - webBuilder.UseStartup(); - }) - .UseAutofac() - .UseSerilog(); } diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/Startup.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/Startup.cs deleted file mode 100644 index 4500cd8c22..0000000000 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/Startup.cs +++ /dev/null @@ -1,17 +0,0 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.Extensions.DependencyInjection; - -namespace MyCompanyName.MyProjectName.Web; - -public class Startup -{ - public void ConfigureServices(IServiceCollection services) - { - services.AddApplication(); - } - - public void Configure(IApplicationBuilder app) - { - app.InitializeApplication(); - } -} diff --git a/templates/console/src/MyCompanyName.MyProjectName/HelloWorldService.cs b/templates/console/src/MyCompanyName.MyProjectName/HelloWorldService.cs index 7ddd618c3e..7c095b85ed 100644 --- a/templates/console/src/MyCompanyName.MyProjectName/HelloWorldService.cs +++ b/templates/console/src/MyCompanyName.MyProjectName/HelloWorldService.cs @@ -1,12 +1,22 @@ -using System; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; using Volo.Abp.DependencyInjection; namespace MyCompanyName.MyProjectName; public class HelloWorldService : ITransientDependency { - public void SayHello() + public ILogger Logger { get; set; } + + public HelloWorldService() + { + Logger = NullLogger.Instance; + } + + public Task SayHelloAsync() { - Console.WriteLine("\tHello World!"); + Logger.LogInformation("Hello World!"); + return Task.CompletedTask; } } diff --git a/templates/console/src/MyCompanyName.MyProjectName/MyCompanyName.MyProjectName.csproj b/templates/console/src/MyCompanyName.MyProjectName/MyCompanyName.MyProjectName.csproj index 2ea0513d71..a2041bf970 100644 --- a/templates/console/src/MyCompanyName.MyProjectName/MyCompanyName.MyProjectName.csproj +++ b/templates/console/src/MyCompanyName.MyProjectName/MyCompanyName.MyProjectName.csproj @@ -14,6 +14,7 @@ + diff --git a/templates/console/src/MyCompanyName.MyProjectName/MyProjectNameHostedService.cs b/templates/console/src/MyCompanyName.MyProjectName/MyProjectNameHostedService.cs index 822844e10e..756d56571e 100644 --- a/templates/console/src/MyCompanyName.MyProjectName/MyProjectNameHostedService.cs +++ b/templates/console/src/MyCompanyName.MyProjectName/MyProjectNameHostedService.cs @@ -1,40 +1,46 @@ -using System; -using System.Threading; +using System.Threading; using System.Threading.Tasks; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; +using Serilog; using Volo.Abp; namespace MyCompanyName.MyProjectName; public class MyProjectNameHostedService : IHostedService { - private readonly IAbpApplicationWithExternalServiceProvider _application; - private readonly IServiceProvider _serviceProvider; - private readonly HelloWorldService _helloWorldService; - - public MyProjectNameHostedService( - IAbpApplicationWithExternalServiceProvider application, - IServiceProvider serviceProvider, - HelloWorldService helloWorldService) + private IAbpApplicationWithInternalServiceProvider _abpApplication; + + private readonly IConfiguration _configuration; + private readonly IHostEnvironment _hostEnvironment; + + public MyProjectNameHostedService(IConfiguration configuration, IHostEnvironment hostEnvironment) { - _application = application; - _serviceProvider = serviceProvider; - _helloWorldService = helloWorldService; + _configuration = configuration; + _hostEnvironment = hostEnvironment; } - public Task StartAsync(CancellationToken cancellationToken) + public async Task StartAsync(CancellationToken cancellationToken) { - _application.Initialize(_serviceProvider); + _abpApplication = await AbpApplicationFactory.CreateAsync(options => + { + options.Services.ReplaceConfiguration(_configuration); + options.Services.AddSingleton(_hostEnvironment); + + options.UseAutofac(); + options.Services.AddLogging(loggingBuilder => loggingBuilder.AddSerilog(dispose: true)); + }); - _helloWorldService.SayHello(); + await _abpApplication.InitializeAsync(); - return Task.CompletedTask; + var helloWorldService = _abpApplication.ServiceProvider.GetRequiredService(); + + await helloWorldService.SayHelloAsync(); } - public Task StopAsync(CancellationToken cancellationToken) + public async Task StopAsync(CancellationToken cancellationToken) { - _application.Shutdown(); - - return Task.CompletedTask; + await _abpApplication.ShutdownAsync(); } } diff --git a/templates/console/src/MyCompanyName.MyProjectName/MyProjectNameModule.cs b/templates/console/src/MyCompanyName.MyProjectName/MyProjectNameModule.cs index 15ff448d74..c7045a62ea 100644 --- a/templates/console/src/MyCompanyName.MyProjectName/MyProjectNameModule.cs +++ b/templates/console/src/MyCompanyName.MyProjectName/MyProjectNameModule.cs @@ -1,5 +1,9 @@ -using Microsoft.Extensions.DependencyInjection; +using System.Threading.Tasks; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Volo.Abp; using Volo.Abp.Autofac; using Volo.Abp.Modularity; @@ -10,11 +14,15 @@ namespace MyCompanyName.MyProjectName; )] public class MyProjectNameModule : AbpModule { - public override void ConfigureServices(ServiceConfigurationContext context) + public override Task OnApplicationInitializationAsync(ApplicationInitializationContext context) { - var configuration = context.Services.GetConfiguration(); - var hostEnvironment = context.Services.GetSingletonInstance(); + var logger = context.ServiceProvider.GetRequiredService>(); + var configuration = context.ServiceProvider.GetRequiredService(); + logger.LogInformation($"MySettingName => {configuration["MySettingName"]}"); - context.Services.AddHostedService(); + var hostEnvironment = context.ServiceProvider.GetRequiredService(); + logger.LogInformation($"EnvironmentName => {hostEnvironment.EnvironmentName}"); + + return Task.CompletedTask; } } diff --git a/templates/console/src/MyCompanyName.MyProjectName/Program.cs b/templates/console/src/MyCompanyName.MyProjectName/Program.cs index 1ec4de497c..c6317e635d 100644 --- a/templates/console/src/MyCompanyName.MyProjectName/Program.cs +++ b/templates/console/src/MyCompanyName.MyProjectName/Program.cs @@ -1,6 +1,5 @@ using System; using System.Threading.Tasks; -using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Serilog; @@ -10,7 +9,7 @@ namespace MyCompanyName.MyProjectName; public class Program { - public static async Task Main(string[] args) + public async static Task Main(string[] args) { Log.Logger = new LoggerConfiguration() #if DEBUG @@ -27,7 +26,14 @@ public class Program try { Log.Information("Starting console host."); - await CreateHostBuilder(args).RunConsoleAsync(); + + await Host.CreateDefaultBuilder(args) + .ConfigureServices(services => + { + services.AddHostedService(); + }) + .RunConsoleAsync(); + return 0; } catch (Exception ex) @@ -39,19 +45,5 @@ public class Program { Log.CloseAndFlush(); } - } - - internal static IHostBuilder CreateHostBuilder(string[] args) => - Host.CreateDefaultBuilder(args) - .UseAutofac() - .UseSerilog() - .ConfigureAppConfiguration((context, config) => - { - //setup your additional configuration sources - }) - .ConfigureServices((hostContext, services) => - { - services.AddApplication(); - }); } diff --git a/templates/console/src/MyCompanyName.MyProjectName/appsettings.json b/templates/console/src/MyCompanyName.MyProjectName/appsettings.json index 0db3279e44..1bc4c59014 100644 --- a/templates/console/src/MyCompanyName.MyProjectName/appsettings.json +++ b/templates/console/src/MyCompanyName.MyProjectName/appsettings.json @@ -1,3 +1,3 @@ { - + "MySettingName": "MySettingValue" } diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Host/Program.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Host/Program.cs index d5b3c36ff5..d0e58677bd 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Host/Program.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Host/Program.cs @@ -5,11 +5,11 @@ namespace MyCompanyName.MyProjectName.Blazor.Host; public class Program { - public static async Task Main(string[] args) + public async static Task Main(string[] args) { var builder = WebAssemblyHostBuilder.CreateDefault(args); - var application = builder.AddApplication(options => + var application = await builder.AddApplicationAsync(options => { options.UseAutofac(); }); diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/MyProjectNameBlazorHostModule.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/MyProjectNameBlazorHostModule.cs index 951a9e69bc..fdb57b3435 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/MyProjectNameBlazorHostModule.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/MyProjectNameBlazorHostModule.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Net.Http; +using System.Threading.Tasks; using Blazorise.Bootstrap5; using Blazorise.Icons.FontAwesome; using Microsoft.AspNetCore.Builder; @@ -211,7 +212,7 @@ public class MyProjectNameBlazorHostModule : AbpModule #endif } - public override void OnApplicationInitialization(ApplicationInitializationContext context) + public async override Task OnApplicationInitializationAsync(ApplicationInitializationContext context) { var env = context.GetEnvironment(); var app = context.GetApplicationBuilder(); @@ -252,12 +253,9 @@ public class MyProjectNameBlazorHostModule : AbpModule using (var scope = context.ServiceProvider.CreateScope()) { - AsyncHelper.RunSync(async () => - { - await scope.ServiceProvider - .GetRequiredService() - .SeedAsync(); - }); + await scope.ServiceProvider + .GetRequiredService() + .SeedAsync(); } } } diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Program.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Program.cs index 1301cbfb3e..c1b5c178d5 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Program.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Program.cs @@ -1,6 +1,7 @@ using System; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Serilog; using Serilog.Events; @@ -9,27 +10,37 @@ namespace MyCompanyName.MyProjectName.Blazor.Server.Host; public class Program { - public static int Main(string[] args) + public async static Task Main(string[] args) { Log.Logger = new LoggerConfiguration() #if DEBUG - .MinimumLevel.Debug() + .MinimumLevel.Debug() #else - .MinimumLevel.Information() + .MinimumLevel.Information() #endif - .MinimumLevel.Override("Microsoft", LogEventLevel.Information) + .MinimumLevel.Override("Microsoft", LogEventLevel.Information) .MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning) .Enrich.FromLogContext() .WriteTo.Async(c => c.File("Logs/logs.txt")) #if DEBUG - .WriteTo.Async(c => c.Console()) + .WriteTo.Async(c => c.Console()) #endif - .CreateLogger(); + .CreateLogger(); try { Log.Information("Starting web host."); - CreateHostBuilder(args).Build().Run(); + var builder = WebApplication.CreateBuilder(args); + builder.Host.AddAppSettingsSecretsJson() + .UseAutofac() + .UseSerilog(); + await builder.Services.AddApplicationAsync(options => + { + options.Services.ReplaceConfiguration(builder.Configuration); + }); + var app = builder.Build(); + await app.InitializeApplicationAsync(); + await app.RunAsync(); return 0; } catch (Exception ex) @@ -42,15 +53,4 @@ public class Program Log.CloseAndFlush(); } } - - public static IHostBuilder CreateHostBuilder(string[] args) => - Microsoft.Extensions.Hosting.Host.CreateDefaultBuilder(args) - .AddAppSettingsSecretsJson() - .ConfigureWebHostDefaults(webBuilder => - { - - webBuilder.UseStartup(); - }) - .UseAutofac() - .UseSerilog(); } diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Startup.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Startup.cs deleted file mode 100644 index d356f6bede..0000000000 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Startup.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.DependencyInjection; - -namespace MyCompanyName.MyProjectName.Blazor.Server.Host; - -public class Startup -{ - public void ConfigureServices(IServiceCollection services) - { - services.AddApplication(); - } - - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) - { - app.InitializeApplication(); - } -} diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/Program.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/Program.cs index 500a2cfc00..328016c3b0 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/Program.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/Program.cs @@ -1,7 +1,7 @@ using System; -using System.IO; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Serilog; using Serilog.Events; @@ -10,26 +10,37 @@ namespace MyCompanyName.MyProjectName; public class Program { - public static int Main(string[] args) + public async static Task Main(string[] args) { Log.Logger = new LoggerConfiguration() #if DEBUG - .MinimumLevel.Debug() + .MinimumLevel.Debug() #else - .MinimumLevel.Information() + .MinimumLevel.Information() #endif - .MinimumLevel.Override("Microsoft", LogEventLevel.Information) + .MinimumLevel.Override("Microsoft", LogEventLevel.Information) + .MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning) .Enrich.FromLogContext() .WriteTo.Async(c => c.File("Logs/logs.txt")) #if DEBUG - .WriteTo.Async(c => c.Console()) + .WriteTo.Async(c => c.Console()) #endif - .CreateLogger(); + .CreateLogger(); try { Log.Information("Starting web host."); - CreateHostBuilder(args).Build().Run(); + var builder = WebApplication.CreateBuilder(args); + builder.Host.AddAppSettingsSecretsJson() + .UseAutofac() + .UseSerilog(); + await builder.Services.AddApplicationAsync(options => + { + options.Services.ReplaceConfiguration(builder.Configuration); + }); + var app = builder.Build(); + await app.InitializeApplicationAsync(); + await app.RunAsync(); return 0; } catch (Exception ex) @@ -42,14 +53,4 @@ public class Program Log.CloseAndFlush(); } } - - internal static IHostBuilder CreateHostBuilder(string[] args) => - Host.CreateDefaultBuilder(args) - .AddAppSettingsSecretsJson() - .ConfigureWebHostDefaults(webBuilder => - { - webBuilder.UseStartup(); - }) - .UseAutofac() - .UseSerilog(); } diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/Startup.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/Startup.cs deleted file mode 100644 index 200da6e542..0000000000 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/Startup.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; - -namespace MyCompanyName.MyProjectName; - -public class Startup -{ - public void ConfigureServices(IServiceCollection services) - { - services.AddApplication(); - } - - public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory) - { - app.InitializeApplication(); - } -} diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs index b6fc071e14..eb854d3bc1 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Cors; using Microsoft.AspNetCore.DataProtection; @@ -187,7 +188,7 @@ public class MyProjectNameIdentityServerModule : AbpModule #endif } - public override void OnApplicationInitialization(ApplicationInitializationContext context) + public async override Task OnApplicationInitializationAsync(ApplicationInitializationContext context) { var app = context.GetApplicationBuilder(); var env = context.GetEnvironment(); @@ -227,19 +228,16 @@ public class MyProjectNameIdentityServerModule : AbpModule app.UseAbpSerilogEnrichers(); app.UseConfiguredEndpoints(); - SeedData(context); + await SeedData(context); } - private void SeedData(ApplicationInitializationContext context) + private async Task SeedData(ApplicationInitializationContext context) { - AsyncHelper.RunSync(async () => + using (var scope = context.ServiceProvider.CreateScope()) { - using (var scope = context.ServiceProvider.CreateScope()) - { - await scope.ServiceProvider - .GetRequiredService() - .SeedAsync(); - } - }); + await scope.ServiceProvider + .GetRequiredService() + .SeedAsync(); + } } } diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/Program.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/Program.cs index 500a2cfc00..5f5b29332b 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/Program.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/Program.cs @@ -1,7 +1,7 @@ using System; -using System.IO; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Serilog; using Serilog.Events; @@ -10,26 +10,37 @@ namespace MyCompanyName.MyProjectName; public class Program { - public static int Main(string[] args) + public async static Task Main(string[] args) { Log.Logger = new LoggerConfiguration() #if DEBUG - .MinimumLevel.Debug() + .MinimumLevel.Debug() #else - .MinimumLevel.Information() + .MinimumLevel.Information() #endif - .MinimumLevel.Override("Microsoft", LogEventLevel.Information) + .MinimumLevel.Override("Microsoft", LogEventLevel.Information) + .MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning) .Enrich.FromLogContext() .WriteTo.Async(c => c.File("Logs/logs.txt")) #if DEBUG - .WriteTo.Async(c => c.Console()) + .WriteTo.Async(c => c.Console()) #endif - .CreateLogger(); + .CreateLogger(); try { Log.Information("Starting web host."); - CreateHostBuilder(args).Build().Run(); + var builder = WebApplication.CreateBuilder(args); + builder.Host.AddAppSettingsSecretsJson() + .UseAutofac() + .UseSerilog(); + await builder.Services.AddApplicationAsync(options => + { + options.Services.ReplaceConfiguration(builder.Configuration); + }); + var app = builder.Build(); + await app.InitializeApplicationAsync(); + await app.RunAsync(); return 0; } catch (Exception ex) @@ -42,14 +53,4 @@ public class Program Log.CloseAndFlush(); } } - - internal static IHostBuilder CreateHostBuilder(string[] args) => - Host.CreateDefaultBuilder(args) - .AddAppSettingsSecretsJson() - .ConfigureWebHostDefaults(webBuilder => - { - webBuilder.UseStartup(); - }) - .UseAutofac() - .UseSerilog(); } diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/Startup.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/Startup.cs deleted file mode 100644 index 70990fa4da..0000000000 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/Startup.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; - -namespace MyCompanyName.MyProjectName; - -public class Startup -{ - public void ConfigureServices(IServiceCollection services) - { - services.AddApplication(); - } - - public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory) - { - app.InitializeApplication(); - } -} diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Host/Program.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Host/Program.cs index 500a2cfc00..cdeeed1546 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Host/Program.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Host/Program.cs @@ -1,7 +1,10 @@ using System; using System.IO; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Serilog; using Serilog.Events; @@ -10,26 +13,37 @@ namespace MyCompanyName.MyProjectName; public class Program { - public static int Main(string[] args) + public async static Task Main(string[] args) { Log.Logger = new LoggerConfiguration() #if DEBUG - .MinimumLevel.Debug() + .MinimumLevel.Debug() #else - .MinimumLevel.Information() + .MinimumLevel.Information() #endif - .MinimumLevel.Override("Microsoft", LogEventLevel.Information) + .MinimumLevel.Override("Microsoft", LogEventLevel.Information) + .MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning) .Enrich.FromLogContext() .WriteTo.Async(c => c.File("Logs/logs.txt")) #if DEBUG - .WriteTo.Async(c => c.Console()) + .WriteTo.Async(c => c.Console()) #endif - .CreateLogger(); + .CreateLogger(); try { Log.Information("Starting web host."); - CreateHostBuilder(args).Build().Run(); + var builder = WebApplication.CreateBuilder(args); + builder.Host.AddAppSettingsSecretsJson() + .UseAutofac() + .UseSerilog(); + await builder.Services.AddApplicationAsync(options => + { + options.Services.ReplaceConfiguration(builder.Configuration); + }); + var app = builder.Build(); + await app.InitializeApplicationAsync(); + await app.RunAsync(); return 0; } catch (Exception ex) @@ -42,14 +56,4 @@ public class Program Log.CloseAndFlush(); } } - - internal static IHostBuilder CreateHostBuilder(string[] args) => - Host.CreateDefaultBuilder(args) - .AddAppSettingsSecretsJson() - .ConfigureWebHostDefaults(webBuilder => - { - webBuilder.UseStartup(); - }) - .UseAutofac() - .UseSerilog(); } diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Host/Startup.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Host/Startup.cs deleted file mode 100644 index 265fb2e7d7..0000000000 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Host/Startup.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; - -namespace MyCompanyName.MyProjectName; - -public class Startup -{ - public void ConfigureServices(IServiceCollection services) - { - services.AddApplication(); - } - - public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory) - { - app.InitializeApplication(); - } -} diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/MyProjectNameWebUnifiedModule.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/MyProjectNameWebUnifiedModule.cs index ed4f5d13e9..49b63a407d 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/MyProjectNameWebUnifiedModule.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/MyProjectNameWebUnifiedModule.cs @@ -1,5 +1,6 @@ using System.IO; using System.Reflection; +using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; @@ -140,7 +141,7 @@ public class MyProjectNameWebUnifiedModule : AbpModule #endif } - public override void OnApplicationInitialization(ApplicationInitializationContext context) + public async override Task OnApplicationInitializationAsync(ApplicationInitializationContext context) { var app = context.GetApplicationBuilder(); var env = context.GetEnvironment(); @@ -180,12 +181,9 @@ public class MyProjectNameWebUnifiedModule : AbpModule using (var scope = context.ServiceProvider.CreateScope()) { - AsyncHelper.RunSync(async () => - { - await scope.ServiceProvider - .GetRequiredService() - .SeedAsync(); - }); + await scope.ServiceProvider + .GetRequiredService() + .SeedAsync(); } } } diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Program.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Program.cs index 6b523328cc..a8443ddaca 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Program.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Program.cs @@ -1,7 +1,10 @@ using System; using System.IO; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Serilog; using Serilog.Events; @@ -10,22 +13,37 @@ namespace MyCompanyName.MyProjectName; public class Program { - public static int Main(string[] args) + public async static Task Main(string[] args) { Log.Logger = new LoggerConfiguration() +#if DEBUG .MinimumLevel.Debug() +#else + .MinimumLevel.Information() +#endif .MinimumLevel.Override("Microsoft", LogEventLevel.Information) + .MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning) .Enrich.FromLogContext() .WriteTo.Async(c => c.File("Logs/logs.txt")) #if DEBUG - .WriteTo.Async(c => c.Console()) + .WriteTo.Async(c => c.Console()) #endif - .CreateLogger(); + .CreateLogger(); try { Log.Information("Starting web host."); - CreateHostBuilder(args).Build().Run(); + var builder = WebApplication.CreateBuilder(args); + builder.Host.AddAppSettingsSecretsJson() + .UseAutofac() + .UseSerilog(); + await builder.Services.AddApplicationAsync(options => + { + options.Services.ReplaceConfiguration(builder.Configuration); + }); + var app = builder.Build(); + await app.InitializeApplicationAsync(); + await app.RunAsync(); return 0; } catch (Exception ex) @@ -38,14 +56,4 @@ public class Program Log.CloseAndFlush(); } } - - internal static IHostBuilder CreateHostBuilder(string[] args) => - Host.CreateDefaultBuilder(args) - .AddAppSettingsSecretsJson() - .ConfigureWebHostDefaults(webBuilder => - { - webBuilder.UseStartup(); - }) - .UseAutofac() - .UseSerilog(); } diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Startup.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Startup.cs deleted file mode 100644 index 2be66923ce..0000000000 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Startup.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; - -namespace MyCompanyName.MyProjectName; - -public class Startup -{ - public void ConfigureServices(IServiceCollection services) - { - services.AddApplication(); - } - - public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory) - { - app.InitializeApplication(); - } -} diff --git a/templates/wpf/src/MyCompanyName.MyProjectName/App.xaml.cs b/templates/wpf/src/MyCompanyName.MyProjectName/App.xaml.cs index ab80f115c1..21124d6400 100644 --- a/templates/wpf/src/MyCompanyName.MyProjectName/App.xaml.cs +++ b/templates/wpf/src/MyCompanyName.MyProjectName/App.xaml.cs @@ -1,7 +1,6 @@ using System; using System.Windows; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; using Serilog; using Serilog.Events; using Volo.Abp; @@ -13,35 +12,34 @@ namespace MyCompanyName.MyProjectName; /// public partial class App : Application { - private readonly IHost _host; - private readonly IAbpApplicationWithExternalServiceProvider _application; + private IAbpApplicationWithInternalServiceProvider _abpApplication; - public App() + protected async override void OnStartup(StartupEventArgs e) { Log.Logger = new LoggerConfiguration() #if DEBUG - .MinimumLevel.Debug() + .MinimumLevel.Debug() #else - .MinimumLevel.Information() + .MinimumLevel.Information() #endif - .MinimumLevel.Override("Microsoft", LogEventLevel.Information) + .MinimumLevel.Override("Microsoft", LogEventLevel.Information) .Enrich.FromLogContext() .WriteTo.Async(c => c.File("Logs/logs.txt")) .CreateLogger(); - _host = CreateHostBuilder(); - _application = _host.Services.GetService(); - } - - protected override async void OnStartup(StartupEventArgs e) - { try { Log.Information("Starting WPF host."); - await _host.StartAsync(); - Initialize(_host.Services); - _host.Services.GetService()?.Show(); + _abpApplication = await AbpApplicationFactory.CreateAsync(options => + { + options.UseAutofac(); + options.Services.AddLogging(loggingBuilder => loggingBuilder.AddSerilog(dispose: true)); + }); + + await _abpApplication.InitializeAsync(); + + _abpApplication.Services.GetRequiredService()?.Show(); } catch (Exception ex) @@ -50,28 +48,9 @@ public partial class App : Application } } - protected override async void OnExit(ExitEventArgs e) + protected async override void OnExit(ExitEventArgs e) { - _application.Shutdown(); - await _host.StopAsync(); - _host.Dispose(); + await _abpApplication.ShutdownAsync(); Log.CloseAndFlush(); } - - private void Initialize(IServiceProvider serviceProvider) - { - _application.Initialize(serviceProvider); - } - - private IHost CreateHostBuilder() - { - return Host - .CreateDefaultBuilder(null) - .UseAutofac() - .UseSerilog() - .ConfigureServices((hostContext, services) => - { - services.AddApplication(); - }).Build(); - } } diff --git a/templates/wpf/src/MyCompanyName.MyProjectName/HelloWorldService.cs b/templates/wpf/src/MyCompanyName.MyProjectName/HelloWorldService.cs index 35127360b8..2c88a265e0 100644 --- a/templates/wpf/src/MyCompanyName.MyProjectName/HelloWorldService.cs +++ b/templates/wpf/src/MyCompanyName.MyProjectName/HelloWorldService.cs @@ -1,11 +1,20 @@ -using Volo.Abp.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using Volo.Abp.DependencyInjection; namespace MyCompanyName.MyProjectName; public class HelloWorldService : ITransientDependency { + public ILogger Logger { get; set; } + + public HelloWorldService() + { + Logger = NullLogger.Instance; + } public string SayHello() { - return "\tHello world!"; + Logger.LogInformation("Call SayHello"); + return "Hello world!"; } } diff --git a/templates/wpf/src/MyCompanyName.MyProjectName/MyCompanyName.MyProjectName.csproj b/templates/wpf/src/MyCompanyName.MyProjectName/MyCompanyName.MyProjectName.csproj index afb8fcfb4c..6b5352c3e7 100644 --- a/templates/wpf/src/MyCompanyName.MyProjectName/MyCompanyName.MyProjectName.csproj +++ b/templates/wpf/src/MyCompanyName.MyProjectName/MyCompanyName.MyProjectName.csproj @@ -15,6 +15,7 @@ +