1

I am working with a .Net WinForms Application that is being designed to collect records from MongoDB and insert records into a SQL Server database.

The error that I am getting below is flagged at Application.Run(...)

System.InvalidOperationException: 'Cannot resolve 'FixSqlChatHistory.WinForm.MongoReader' from root provider because it requires scoped service 'FixSqlChatHistory.DataContext.MongoToSqlContext'.'

The code I am working with is

static void Main()
{
    Application.SetHighDpiMode(HighDpiMode.SystemAware);
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);

    var host = CreateHostBuilder().Build();
    ServiceProvider = host.Services;

    Application.Run(ServiceProvider.GetRequiredService<MongoReader>());
}

public static IServiceProvider ServiceProvider { get; private set; }
static IHostBuilder CreateHostBuilder()
{
    var assemblies = AppDomain.CurrentDomain.GetAssemblies()
        .Where(x => x.GetName().Name.Contains("FixSqlHistory"));

    var builder = new ConfigurationBuilder()
        .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
    Configuration = builder.Build();

    return Host.CreateDefaultBuilder()
        .ConfigureServices((context, services) => {
            services.AddScoped<IMongoReader, MongoService>();
            services.AddScoped<IChatActivityReader, ChatDataFixService>();
            services.AddScoped<IChatActivityWriter, ChatDataFixService>();
            services.AddAutoMapper(assemblies);
            
            services.AddDbContext<MongoToSqlContext>(options => options.
                UseSqlServer(Configuration.GetConnectionString("DefaultConnection")))
            services.AddScoped<MongoReader>();


        });
}

The MongoReader (Form) is constructed like this

public MongoReader(
    MongoToSqlContext databaseContext,
    IChatActivityReader chatActivityReader,
    IChatActivityWriter chatActivityWriter,
    IMongoReader mongoReader)
{
    _databaseContext = databaseContext;
    _chatActivityReader = chatActivityReader;
    _chatActivityWriter = chatActivityWriter;
    _mongoReader = mongoReader;
    InitializeComponent();
}

Its been a long time since I created a WinForms Application, and the first time in .Net6 so would appreciate some assistance in where I have gone wrong.

I have looked here which appears to be a similar issue but I am setup with AddScoped as this post suggests

Cannot resolve 'ServiceBusConsumer' from root provider because it requires scoped service DbContext

Simon Price
  • 3,011
  • 3
  • 34
  • 98
  • Have you tried adding the form as transient to the ServiceCollection? – Caveman74 Oct 17 '22 at 14:13
  • @Caveman74, yes I tried that and get the exact same error – Simon Price Oct 17 '22 at 14:31
  • I don't know WinForms in with SQL injection, so I cannot provide a clear solution at this point. The problem seems to be that either you are not defining the IoC scope or that in WinForms nothing is scoped so all must be registered as AddSingleton()? Learn about the scopes in WinForms and you'll be able to solve this. – José Ramírez Oct 17 '22 at 15:01

1 Answers1

1

You need to either create scope manually:

static void Main()
{
    // ...
    ServiceProvider = host.Services;

    using var scope = ServiceProvider.CreateScope();

    Application.Run(scope.ServiceProvider.GetRequiredService<MongoReader>());
}

Or register everything with corresponding lifetime (AddDbContext allows to specify context lifetime which differs from the default Scoped one).

Note that depending on the app you potentially will not want to have the same context used for all it's lifetime.

Guru Stron
  • 102,774
  • 10
  • 95
  • 132