Base solution for your next web application

Activities of "Web2workNL"

Hi, thanks for preparing a blog post and a sample project. However, the link you sent leads to a 404 page.

Thank you for the response. I tried the solution. 2 issues:

  1. The IServiceCollection does not contain a definition for AddApplication on builder.Services.AddApplication<MyFunctionsModule>().
  2. The type or namespace IAbpApplicationWithExternalServiceProvider could not be found on serviceProvider.GetRequiredService<IAbpApplicationWithExternalServiceProvider>().Initialize(serviceProvider);.

After further debugging, I discovered that moving all the Initialize() into the function it allows it to start properly. The function project is runnig the In-process model. When using the Initialize() in my startup.cs, I get the following error: Cannot access a disposed object. Object name: 'IServiceProvider'.

If using the Initialize() inside the function you can successfully execute a test method from my controller inside the Core project. However, when I run my method with a UnitOfWorkManager, I encounter the following error: System.Private.CoreLib: Exception while executing function: MyFunction. Castle.Windsor: Component Abp.Domain.Uow.UnitOfWorkDefaultOptions could not be registered. There is already a component with that name. Did you want to modify the existing component instead? If not, make sure you specify a unique name.

My Function:

public class MyFunction
{
    private readonly ILogger<MyFunction> _logger;

    public MyFunction(ILogger<MyFunction> logger)
    {
        _logger = logger;
    }

    [FunctionName(nameof(MyFunction))]
    public async Task Run([QueueTrigger("my-queue", Connection = "myConnString")] QueueMessage message)
    {
        using (var bootstrapper = AbpBootstrapper.Create<MyFunctionModule>())
        {
            // initialize here or in startup.cs - performance for starting function?
            bootstrapper.Initialize();

            using (var myCoreController = bootstrapper.IocManager.ResolveAsDisposable<IMyCoreController>())
            {
                // works fine
                var test = await myCoreController.Object.Test();
                _logger.LogInformation(test);

                // generates error:
                await myCoreController.Object.MyMethod();

            }
        }
    }
}

Startup: (if used, it fails to start function)

[assembly: FunctionsStartup(typeof(Startup))]

namespace MyFunctionsNameSpace
{
    public class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
            using (var bootstrapper = AbpBootstrapper.Create<MyFunctionModule>())
            {
                bootstrapper.Initialize();
            }
        }
    }
}

MyMethod - inside MyCoreController

private async Task MyMethod()
{
    using (var uow = UnitOfWorkManager.Begin())
    {
        // code fails on first call the repository

        ...
        
        uow.Complete();
    }
}

MyFunctionModule

[DependsOn(typeof(MyProjectEntityFrameworkCoreModule))]
public class MyFunctionModule: AbpModule
{
    private readonly IConfigurationRoot _appConfiguration;

    public MyFunctionModule(MyProjectEntityFrameworkCoreModule abpZeroTemplateEntityFrameworkCoreModule)
    {
        abpZeroTemplateEntityFrameworkCoreModule.SkipDbSeed = true;

        _appConfiguration = AppConfigurations.Get(
            typeof(MyFunctionModule).GetAssembly().GetDirectoryPathOrNull()
        );
    }

    public override void PreInitialize()
    {
        Configuration.DefaultNameOrConnectionString = _appConfiguration.GetConnectionString("...");
        Configuration.Modules.AspNetZero().LicenseCode = _appConfiguration["..."];
    }

    public override void Initialize()
    {
        IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
        ServiceCollectionRegistrar.Register(IocManager);
    }
}

Hi,

I've been trying to get my Azure Function (project is running Abp 9.2.2) to work, but I'm encountering some issues.

I followed the code example above, but I ran into a couple of problems. The _bootstrapper.IocManager.Resolve<>() method requires the arguments to be explicitly specified, as does the AbpBootstrapper.Create() method. For AbpBootstrapper.Create(), I assume you can use your own ProjectModule : AbpModule.

When I implement the standard approach for creating Console application projects (similar to the Migrator project), I encounter dependency injection errors related to IServiceProvider or IUnitOfWorkManager.

Is there an example Azure Functions project available, or could you provide guidance on how to resolve these issues?

Thanks.

thanks for the hint. solution implemented

Thanks for the suggestion! I was unaware that ABP had something similar out of the box 👍.

I have a few questions about the implementation of the PerRequestRedisCache though

  • Does this cache stuff to memory like the MemoryCache implementation does, or does it cache for the specific current connection so THIS user doesn't have to go to redis if they need the same value again
  • We have a scale out solution with multiple instances, so we've set the expiry on the memory cache really low so it expires quickly and is updated from Redis frequently. Is it possible to set the expiry of the memorycache with PerRequestRedisCache?

Yes, the PermissionManager is created through dependency injection. So is the _session btw private readonly IAbpSession _session;

The background job is not a timed job but is handled like the notifications are (through AbpBackgoundJobs)

  await _backgroundJobManager.EnqueueAsync<SyncWithMooJob, SyncWithMooJobArgs>(new SyncWithMooJobArgs(AbpSession.GetTenantId()));

And

 public class SyncWithMooJob : BackgroundJob<SyncWithMooJobArgs>, ITransientDependency
        {
            private readonly IMooManager _mooSyncManager;
            
            public SyncWithMooJob(IMooManager mooSyncManager)
            {
                _mooSyncManager = mooSyncManager;
            }

            public override void Execute(SyncWithMooJobArgs args)
            {
                AsyncHelper.RunSync(() => _mooSyncManager.AutomaticSyncWithMoo(args.TenantId));
            }
        }
    }

If I strip the method down to just


        public async Task AutomaticSyncWithMoo(int tenantId)
        {
            try
            {
                using (CurrentUnitOfWork.SetTenantId(tenantId))
                {
                   
                    using (_session.Use(tenantId, null))
                    { 
                    var permission = _permissionManager.GetPermissionOrNull(AppPermissions.Pages_Administration_TeacherGroups);
                     }
                } 
            }
            catch (Exception ex)
            {
                Logger.Error(ex.Message + ex.StackTrace);
            }
        }
                    

I still get a NULL result. Just for clarity, when I add _permissionManager.GetPermissionOrNull(AppPermissions.Pages_Administration_TeacherGroups); to for instance an AppService there are no issues

We managed to reproduce the behaviour. Please see the GitHub issue.

Hi JakeE,

We would love to hear from you wether you managed to find a solution to the problem other than expiring the caches after 1 second. We are experiencing the same issues (https://support.aspnetzero.com/QA/Questions/9015)

We know about the possibility to clear the cache by hand, but have been unable to reproduce the corrupted cache after doing this.

It doesn't seem to happen everytime, which is why we assume there is a specific scenario somewhere that leads to the tenant filter not being applied in AbpFeatureValueStore.GetTenantFeatureCacheItem(Async)

We believe that when this scenario presents itself just as the cache has been expired, these two situations together lead to the cache being corrupted. Me and my team have been going through our code to find this scenario, but have not had any luck.

We would be very grateful if you could brainstorm with us on what could possibility lead to this.

Showing 1 to 10 of 11 entries