Adding Autofac to WPF MVVM application
Expanding on my comment above:
I use Autofac with all my WPF MVVM applications, I believe it to be one of the better DI frameworks - this is my opinion, but I think it is valid.
Also for me PRISM should be avoided 99% of the time, it's a 'solution looking for a problem' and since most people don't build dynamically composable runtime solutions in WPF it is not needed, i'm sure people would\will disagree.
Like any architectural patterns there is a setup\configuration phase to the application life-cycle, put simply in your case before the first View (window) is shown there will be a whole of setup done for Dependency Injection, Logging, Exception Handling, Dispatcher thread management, Themes etc.
I have several examples of using Autofac with WPF\MVVM, a couple are listed below, I would say look at the Simple.Wpf.Exceptions example:
https://github.com/oriches/Simple.Wpf.Exceptions
You can use a similar technique as your console application:
class Program{ [STAThread] static void Main(string[] args) { var builder = new ContainerBuilder(); builder.RegisterType<Cleaner>().As<ICleaner>(); builder.RegisterType<Repository>().AsImplementedInterfaces().InstancePerLifetimeScope(); // Add the MainWindowclass and later resolve build.RegisterType<MainWindow>().AsSelf(); var container = builder.Build(); using (var scope = container.BeginLifetimeScope()) { var main = scope.Resolve<MainWindow>(); main.ShowDialog(); } }}
Be sure to mark Main with [STAThread]
. Then in the project's properties, under the Application tab, set the Startup object
to the Program class.
However, I am not certain of the implications of not running App.Run()
and of running MainWindow.ShowDialog()
instead.
To do the same using App.Run()
, do the following:
1) delete StartupUri="MainWindow.xaml"
from App.xaml
2) Add the following to App.xaml.cs
protected override void OnStartup(StartupEventArgs e){ var builder = new ContainerBuilder(); builder.RegisterType<Cleaner>().As<ICleaner>(); builder.RegisterType<Repository>().AsImplementedInterfaces().InstancePerLifetimeScope(); // Add the MainWindowclass and later resolve build.RegisterType<MainWindow>().AsSelf(); var container = builder.Build(); using (var scope = container.BeginLifetimeScope()) { var window = scope.Resolve<MainWindow>(); window.Show(); }}
WPF doesn't have a natural composition root or easy DI integration. Prism is a pretty common set of libraries specifically intended to bridge that for you.
(That's not Autofac specific - it's general guidance for adding DI to WPF apps.)