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 activateMyNamespace.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 activateVolo.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.