0

I'm extending a ABP Commercial application with an isolated Azure Function with .NET 5 and want to inject data from the ABP Framework itself.

This is my code:

public class MyAzureFunction
{
    private readonly IMyRepository _myRepository;

    public MyAzureFunction(IMyRepository myRepository) 
    {
        _myRepository = myRepository;
    }

    [Function("MyAzureFunction")]
    public async Task Run([TimerTrigger("0 */15 * * * *")] TimerInfo myTimer, FunctionContext context)
    {
        ILogger logger = context.GetLogger("MyAzureFunction");
        logger.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");

        List<object> result = await _myRepository.GetAllAsync();

        // Keep going...
    }
}

Here is the code from my Program class of the Azure Function project:

public class Program
{
    public static void Main()
    {
        IHost host = new HostBuilder()
            .ConfigureServices(services =>
            {
                services
                    .AddDbContext<MyAppDbContext>(OptionsAction, ServiceLifetime.Transient);
                    // `MyAppDbContext` inherits from `AbpDbContext<MyAppDbContext>` and implements 
                    // `IIdentityProDbContext` and `ISaasDbContext`.

                services
                    .AddScoped<IDbContextProvider<MyDbContext>, UnitOfWorkDbContextProvider<MyDbContext>>() // added on 2021-11-05
                    .AddScoped<IMyRepository, MyRepository>();
            })
            .ConfigureFunctionsWorkerDefaults()
            .Build();

        host.Run();
    }

    private static void OptionsAction(DbContextOptionsBuilder options)
    {
        options.UseSqlServer(
            Environment.GetEnvironmentVariable("DatabaseConnectionString"), 
            (optionActions) => 
            {
                optionActions.EnableRetryOnFailure(5, TimeSpan.FromSeconds(10), null);
                optionActions.CommandTimeout(10);
            }
        );
    }
}

The MyRepository class inherits from EfCoreRepository<MyAppDbContext, Foo, Guid>:

public class MyRepository : EfCoreRepository<MyAppDbContext, Foo, Guid>, IMyRepository
{
    public ExternalSourceRepository(IDbContextProvider<MyAppDbContext> dbContextProvider) : base(dbContextProvider)
    { }

    public class Task<List<Foo>> GetAllAsync() 
    {
        // Logic here.
    }
}

The problem is when I run the function.

System.InvalidOperationException: unable to resolve service for type Volo.Abp.EntityFrameworkCore.IDbContextProvider<MyNamespace.EntityFrameworkCore.MyAppDbContext> while attempting to activate MyNamespace.Foos.MyRepository.

Is there a way to reuse the dependencies from the ABP framework itself?

I've also tried to create another declaration of IMyRepository that doesn't inherit from EfCoreRepository<MyAppDbContext, Foo, Guid> but the problem here is that I can't access thing the type of ExtraPropertyDictionary object.

public class MyRepository : IMyRepository
{
    private readonly MyAppDbContext _myAppDbContext;

    public ExternalSourceRepository(MyAppDbContext myAppDbContext)
    {
        _myAppDbContext = myAppDbContext;
    }

    public class Task<List<Foo>> GetAllAsync() 
    {
        // Logic here.
    }
}

Update 2021-11-05: I've also tried to register IDbContextProvider<MyDbContext> as UnitOfWorkDbContextProvider<MyDbContext>, but then I've got this exception:

System.InvalidOperationException: unable to resolve service for type Volo.Abp.Uow.IUnitOfWorkManager while attempting to activate Volo.Abp.Uow.EntityFrameworkCore.UnitOfWorkDbContextProvider<MyNamespace.EntityFrameworkCore.MyDbContext>.

Could it work if all the dependencies of the dependencies are registered, but what are they and how could it be done?

Side note: This question continues on my previous one Azure Functions with dependency injection through constructor don't find job functions.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
H. Pauwelyn
  • 13,575
  • 26
  • 81
  • 144

0 Answers0