Search code examples
c#wpf.net-coreautofac

Resolve service with Autofac and IHostBuilder


I have a MVVM wpf app in which i'm trying to implement dependency injection with Autofac.

App.xaml.cs :

public App(){
    // getting config path here
    ...

    var config = new ConfigurationBuilder()
                   .SetBasePath(Directory.GetCurrentDirectory())
                   .AddJsonFile(configFilePath, optional: true, reloadOnChange: true)
                   .Build();

    // Host builder
    host = Host.CreateDefaultBuilder()
       .UseServiceProviderFactory(new AutofacServiceProviderFactory())
       .ConfigureContainer<ContainerBuilder>(builder =>
        {
            builder.RegisterModule(new ConfigurationModule(config));
            builder.RegisterType<MyService>().As<IMyService>();
            builder.RegisterType<MainViewModel>().As<IMainViewModel>();
            builder.Register(c => c.Resolve<IHttpClientFactory>().CreateClient()).As<HttpClient>();
            _containerBuilder = builder;
        })
       .Build();
}

Then on App startup i want to set my view model datacontext

protected override async void OnStartup(StartupEventArgs e)
{ 
    await host.StartAsync();

    // How to get a reference to my container or scope here to be able to resolve IMainViewModel ?
    var container = ...
    var mainVM = container.Resolve<IMainViewModel>();
    var window = new MainWindow { DataContext = mainVM };
    window.Show();

    base.OnStartup(e);

}

How can i resolve my MainViewModel in OnStartup method ?


Solution

  • The service provider from IHost can be used to resolve main view model

    using Microsoft.Extensions.DependencyInjection;
    
    //...
    
    protected override async void OnStartup(StartupEventArgs e) { 
        await host.StartAsync();
    
        IServiceProvider services = host.Services;
                
        IMainViewModel mainVM = services.GetService<IMainViewModel>();
    
        var window = new MainWindow { DataContext = mainVM };
        window.Show();
    
        base.OnStartup(e);
    
    }
    

    It will call the Autofac container under the hood. The service provider is just an abstraction on top of the Autofac container since

    .UseServiceProviderFactory(new AutofacServiceProviderFactory())
    

    was invoked.