Hi @maliming
I’ve been working on a project built with MAUI-Blazor, but I’m encountering some critical issues:
On Android, the application crashes instantly at launch. On Windows (non-UWP), I’m getting the following error:
Unhandled exception. System.Runtime.InteropServices.COMException (0x80040154): Classe non enregistr�e (0x80040154 (REGDB_E_CLASSNOTREG))
at System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(Int32 errorCode)
at WinRT.ActivationFactory.Get(String typeName)
at Microsoft.Windows.ApplicationModel.WindowsAppRuntime.DeploymentInitializeOptions.get__objRef_global__Microsoft_Windows_ApplicationModel_WindowsAppRuntime_DeploymentInitializeOptions()
at Microsoft.Windows.ApplicationModel.WindowsAppRuntime.DeploymentInitializeOptions..ctor()
at Microsoft.Windows.ApplicationModel.WindowsAppRuntime.DeploymentManagerCS.AutoInitialize.get_Options() in C:\Users\vivie\.nuget\packages\microsoft.windowsappsdk\1.6.240923002\include\DeploymentManagerAutoInitializer.cs:line 44
at Microsoft.Windows.ApplicationModel.WindowsAppRuntime.DeploymentManagerCS.AutoInitialize.AccessWindowsAppSDK() in C:\Users\vivie\.nuget\packages\microsoft.windowsappsdk\1.6.240923002\include\DeploymentManagerAutoInitializer.cs:line 30
at .cctor()
To troubleshoot, I tested a fresh MAUI-Blazor project, which worked perfectly. Based on this, I suspect the issue is related to ABP.
Additionally, when building the project using the CLI, I encounter an error during the bundling process. I also noticed that MAUI-Blazor is not available in the ABP Studio GUI.
Could you please assist in identifying the root cause or provide any guidance on resolving this?
Thanks in advance for your help!
We can't use WeTransfer sorry.
I send you an email with the link to download.
Hi Shiwei,
Thank you for sharing your email. I just added you to my directory. Thanks again!
Hi,
Thank you for your response. Since you are unable to reproduce the issue, would it be possible to share your email so I can invite you to the project? This way, you can pull the code and run the tests directly to observe the problem.
Thank you for your help!
Thank you for the solution; it's a great idea, and it works for dynamically selecting the Hangfire provider based on the configuration.
However, I am now facing a new issue when running multiple integration tests in sequence. If I run the tests one by one, they pass without any problems. But when I run multiple tests (more than two) together, the first test succeeds, and the subsequent ones fail with the following error:
An error occurred during the initialize Volo.Abp.Modularity.OnApplicationInitializationModuleLifecycleContributor phase of the module Volo.Abp.Identity.AbpIdentityProDomainModule, Volo.Abp.Identity.Pro.Domain, Version=9.0.0.0, Culture=neutral, PublicKeyToken=null: Cannot access a disposed object.
It seems like something is being disposed of between tests, which causes the failure. Could this be related to the Hangfire configuration, or is there something else I need to adjust in my test setup to handle multiple tests properly?
Volo.Abp.AbpInitializationException: An error occurred during the initialize Volo.Abp.Modularity.OnApplicationInitializationModuleLifecycleContributor...
Volo.Abp.AbpInitializationException
An error occurred during the initialize Volo.Abp.Modularity.OnApplicationInitializationModuleLifecycleContributor phase of the module Volo.Abp.Identity.AbpIdentityProDomainModule, Volo.Abp.Identity.Pro.Domain, Version=9.0.0.0, Culture=neutral, PublicKeyToken=null: Cannot access a disposed object.
Object name: 'Hangfire.InMemory.State.Dispatcher`1[[System.UInt64, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]'.. See the inner exception for details.
at Volo.Abp.Modularity.ModuleManager.InitializeModules(ApplicationInitializationContext context)
at Volo.Abp.AbpApplicationBase.InitializeModules()
at Volo.Abp.AbpApplicationWithExternalServiceProvider.Initialize(IServiceProvider serviceProvider)
at Volo.Abp.Testing.AbpIntegratedTest`1..ctor()
at Manuloc.AccuseReceptionCommande.AccuseReceptionCommandeTestBase`1..ctor()
at Manuloc.AccuseReceptionCommande.AccuseReceptionCommandeApplicationTestBase`1..ctor()
at Manuloc.AccuseReceptionCommande.Samples.SampleAppServiceTests`1..ctor() in C:\Users\vivie\RiderProjects\ARC\test\Manuloc.AccuseReceptionCommande.Application.Tests\Samples\SampleAppServiceTests.cs:line 19
at Manuloc.AccuseReceptionCommande.EntityFrameworkCore.Applications.EfCoreSampleAppServiceTests..ctor()
at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean wrapExceptions)
System.ObjectDisposedException
Cannot access a disposed object.
Object name: 'Hangfire.InMemory.State.Dispatcher`1[[System.UInt64, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]'.
at Hangfire.InMemory.State.Dispatcher`1.ThrowObjectDisposedException() in /_/src/Hangfire.InMemory/State/Dispatcher.cs:line 158
at Hangfire.InMemory.State.Dispatcher`1.QueryReadAndWait[TCommand,T](TCommand query, Func`3 func) in /_/src/Hangfire.InMemory/State/Dispatcher.cs:line 95
at Hangfire.InMemory.InMemoryConnection`1.GetAllEntriesFromHash(String key) in /_/src/Hangfire.InMemory/InMemoryConnection.cs:line 408
at Hangfire.RecurringJobExtensions.GetOrCreateRecurringJob(IStorageConnection connection, String recurringJobId) in C:\projects\hangfire-525\src\Hangfire.Core\RecurringJobExtensions.cs:line 62
at Hangfire.RecurringJobManager.AddOrUpdate(String recurringJobId, Job job, String cronExpression, RecurringJobOptions options) in C:\projects\hangfire-525\src\Hangfire.Core\RecurringJobManager.cs:line 115
at Hangfire.RecurringJob.AddOrUpdate(String recurringJobId, String queue, Expression`1 methodCall, String cronExpression, RecurringJobOptions options) in C:\projects\hangfire-525\src\Hangfire.Core\RecurringJob.cs:line 568
at Volo.Abp.BackgroundWorkers.Hangfire.HangfireBackgroundWorkerManager.AddAsync(IBackgroundWorker worker, CancellationToken cancellationToken)
at Volo.Abp.Identity.AbpIdentityProDomainModule.OnApplicationInitializationAsync(ApplicationInitializationContext context)
at Nito.AsyncEx.Synchronous.TaskExtensions.WaitAndUnwrapException(Task task)
at Nito.AsyncEx.AsyncContext.<>c__DisplayClass15_0.<Run>b__0(Task t)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
--- End of stack trace from previous location ---
at Nito.AsyncEx.Synchronous.TaskExtensions.WaitAndUnwrapException(Task task)
at Nito.AsyncEx.AsyncContext.Run(Func`1 action)
at Volo.Abp.Threading.AsyncHelper.RunSync(Func`1 action)
at Volo.Abp.Identity.AbpIdentityProDomainModule.OnApplicationInitialization(ApplicationInitializationContext context)
at Volo.Abp.Modularity.OnApplicationInitializationModuleLifecycleContributor.Initialize(ApplicationInitializationContext context, IAbpModule module)
at Volo.Abp.Modularity.ModuleManager.InitializeModules(ApplicationInitializationContext context)
Thank you for your reply.
The issue I am facing is that when running the tests, the ConfigureServices method in my ApplicationModule is executed, and it attempts to configure Hangfire using PostgreSQL with the line:
options.UseNpgsqlConnection(context.Services.GetConfiguration().GetConnectionString("Default"));
This fails during the tests, as expected, because I should not be using PostgreSQL in the test environment but rather the In-Memory provider.
What I need is a way to override the Hangfire configuration in the test environment to use the In-Memory provider, while still keeping the PostgreSQL configuration for the application in production.
public class AccuseReceptionCommandeApplicationModule : AbpModule
{
public override async Task OnApplicationInitializationAsync(
ApplicationInitializationContext context)
{
await context.AddBackgroundWorkerAsync<EmailScannerWorker>();
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpAutoMapperOptions>(options => { options.AddMaps<AccuseReceptionCommandeApplicationModule>(); });
ConfigureHangfire(context);
}
private void ConfigureHangfire(ServiceConfigurationContext context)
{
context.Services.AddHangfire(config =>
{
config.UsePostgreSqlStorage(options =>
{
options.UseNpgsqlConnection(context.Services.GetConfiguration().GetConnectionString("Default"));
});
});
Configure<AbpHangfireOptions>(options =>
{
options.ServerOptions = new BackgroundJobServerOptions() { WorkerCount = 3 };
});
}
}
Should I add the following in the TestBaseModule to override the Hangfire configuration for tests?
context.Services.AddHangfire(config => config.UseInMemoryStorage());
If so, how can I ensure this configuration takes precedence over the PostgreSQL configuration in the ApplicationModule when running tests?
Thank you again for your guidance!
Hi,
Thank you for your suggestion regarding the Hangfire.InMemory package. I have already successfully configured Hangfire to use the In-Memory provider for testing purposes.
The challenge I am facing is not about setting up the In-Memory provider itself but about configuring my application to use PostgreSQL in production while switching to the In-Memory provider specifically for integration tests.
I am looking for a solution that allows dynamic configuration, similar to how EF Core supports SQLite in-memory databases for integration testing while using a different database provider (e.g., PostgreSQL) for production. Ideally, I want the integration tests to override the default configuration without modifying the core application setup.
Could you provide guidance on achieving this type of setup for Hangfire?
Thank you for your help!
I am using Hangfire for background jobs and workers in my application. The current configuration is set up in my ApplicationModule as follows:
public override async Task OnApplicationInitializationAsync(
ApplicationInitializationContext context)
{
await context.AddBackgroundWorkerAsync<EmailScannerWorker>();
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpAutoMapperOptions>(options => { options.AddMaps<AccuseReceptionCommandeApplicationModule>(); });
ConfigureHangfire(context);
}
private void ConfigureHangfire(ServiceConfigurationContext context)
{
context.Services.AddHangfire(config =>
{
config.UsePostgreSqlStorage(options =>
{
options.UseNpgsqlConnection(context.Services.GetConfiguration().GetConnectionString("Default"));
});
});
Configure<AbpHangfireOptions>(options =>
{
options.ServerOptions = new BackgroundJobServerOptions() { WorkerCount = 3 };
});
}
I want to configure Hangfire to use an in-memory provider for integration tests, similar to how EF Core uses SQLite in-memory databases for testing. This would allow me to reproduce the behavior of the production code while running tests without relying on a PostgreSQL database.
Could you provide guidance or examples on how to set up Hangfire for this use case? Thank you!
I'm not sure if this is good practice because for the 7.2 update we ended up with a lepton preview package that has since been removed. And during the 7.3 update we also found ourselves with a lepton package in preview.
You have to stay on stable when upgrading.
Hi again, Yes we're not update our templates before stable for our packages. Do you use preview version of CLI ?
Absolutely not, we updated cli to 7.3.0 then did the abp update, we had the update in preview on 3 completely different computers
I'm not sure if this is good practice because for the 7.2 update we ended up with a lepton preview package that has since been removed. And during the 7.3 update we also found ourselves with a lepton package in preview.
You have to stay on stable when upgrading.