DI doesn't work on "Development" environment
takutoy opened this issue · comments
environment
.NET Core 3.0.100
MicroBatchFramework 1.5.0
repro code
class Program
{
static async Task Main(string[] args)
{
await BatchHost.CreateDefaultBuilder()
.UseEnvironment("Development") // works fine if this line is commented out
.ConfigureServices((hostContext, services) =>
{
services.AddScoped<IHoge, Hoge>();
})
.RunBatchEngineAsync<MyFirstBatch>(args);
}
}
public interface IHoge
{
void Test();
}
public class Hoge : IHoge
{
public void Test() => Console.WriteLine("Hoge");
}
public class MyFirstBatch : BatchBase
{
private readonly IHoge hoge;
public MyFirstBatch(IHoge hoge)
{
this.hoge = hoge;
}
public void Hello()
{
hoge.Test();
Console.WriteLine("MyFirstBatch");
}
}
expected
Hoge
MyFirstBatch
actual
Fail to create BatchBase instance. Type:ConsoleApp4.MyFirstBatch
System.InvalidOperationException: Cannot resolve 'ConsoleApp4.MyFirstBatch' from root provider because it requires scoped service 'ConsoleApp4.IHoge'.
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteValidator.ValidateResolution(Type serviceType, IServiceScope scope, IServiceScope rootScope)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.Microsoft.Extensions.DependencyInjection.ServiceLookup.IServiceProviderEngineCallback.OnResolve(Type serviceType, IServiceScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
at MicroBatchFramework.BatchEngine.RunCore(BatchContext ctx, Type type, MethodInfo methodInfo, String[] args, Int32 argsOffset)
I found a workaround: use AddSingleton() or AddTransient() instead of AddScoped().
(I just copied AddScoped() from ASP.NET Core sample!)
Same problem occurred on EF Core AddDbContext(), but it can be avoidable by setting ServiceLifetime.
from:
services.AddScoped<IHoge, Hoge>();
services.AddDbContext<BookDbContext>(opt => opt.UseInMemoryDatabase("foo"));
to:
services.AddSingleton<IHoge, Hoge>();
services.AddDbContext<BookDbContext>(opt => opt.UseInMemoryDatabase("foo"), ServiceLifetime.Singleton);
Thank you for reporting!
I've released ver 1.6.0
, it includes fix about this issue.
thank you for the quick fix. MicroBatchFramework saves my batch life!