I'm developing my own application to learn something new. It's WPF .net Core 3.1 app using MVVM pattern.
Recently I've decided to include Microsoft DependencyInjection library.
I've removed StartupUri and modifiec app.xaml.cs:
public IServiceProvider ServiceProvider { get; private set; }
public IConfiguration Configuration { get; private set; }
protected override void OnStartup(StartupEventArgs e)
{
AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve;
InitializeCefSharp();
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
Configuration = builder.Build();
var serviceCollection = new ServiceCollection();
ConfigureServices(serviceCollection);
ServiceProvider = serviceCollection.BuildServiceProvider();
var mainWindow = ServiceProvider.GetRequiredService<MainWindow>();
mainWindow.Show();
}
private void ConfigureServices(IServiceCollection services)
{
services.Configure<AppSettings>
(Configuration.GetSection(nameof(AppSettings)));
// Views
services.AddSingleton<MainWindow>();
services.AddSingleton<SettingsView>();
services.AddSingleton<WwwView>();
services.AddSingleton<BuildingView>();
services.AddSingleton<TroopsMovementsView>();
// ViewModels
services.AddSingleton<MainWindowViewModel>();
services.AddSingleton<SettingsViewModel>();
services.AddSingleton<WwwViewModel>();
services.AddSingleton<DomainViewModel>();
services.AddSingleton<WorldViewModel>();
services.AddSingleton<RegisterViewModel>();
}
I'm setting DataContext inside Views' constructors. All views except MainWindow are UserControl type.
private readonly MainWindowViewModel _mainWindowViewModel;
public MainWindow(MainWindowViewModel mainWindowViewModel)
{
_mainWindowViewModel = mainWindowViewModel;
DataContext = _mainWindowViewModel;
InitializeComponent();
}
private readonly SettingsViewModel _settingsViewModel;
public SettingsView(SettingsViewModel settingsViewModel)
{
_settingsViewModel = settingsViewModel;
DataContext = settingsViewModel;
InitializeComponent();
}
All Views are embedded in MainWindow like this:
<dz:DockControl Grid.Row="3" Loaded="FrameworkElement_OnLoaded">
<dz:DockItem x:Name="Settings" TabText="Settings" ShowAction="{dz:ShowAsDockPositionAction DockPosition=RightAutoHide}">
<views:SettingsView/>
</dz:DockItem>
<dz:DockItem x:Name="WWW" TabText="WWW" ShowAction="{dz:ShowAsDockPositionAction DockPosition=Document}" DefaultDockPosition="Document" >
<views:WwwView/>
</dz:DockItem>
</dz:DockControl>
It's visual studio-like docking library.
The problem is that I got exception during startup, that there's no parameterless constructor. But I can not have any parameterless constructors as I need Views to get ViewModels injected. ViewModels to get repositories injected.
When I've created 2nd ocnstructor which is parameterless, there's strange things happening - Views doesn't load inside MainWindow or load, but doesn't use ViewModels.
If I'm setting DataContext in xaml file, Views got parameterless constructors, but then ViewModels must have parameterless constructors...
<UserControl.DataContext>
<vm:SettingsViewModel/>
</UserControl.DataContext>
How to correctly use Dependency injection in my case?