Cysharp / ConsoleAppFramework

Zero Dependency, Zero Overhead, Zero Reflection, Zero Allocation, AOT Safe CLI Framework powered by C# Source Generator.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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!