High!
I am trying to replace the default IViewLocator of ReactiveUi/Splat in WPF. I am using AutoFac as container.
My goal is very simple: ReactiveUi/Splat should use my custom implementation of IViewLocator when resolving a view for view model.
I really read every availabe tutorial and stackoverflow thread, but nothing helped.
Currently I do the following while bootstrapping: (I tried many different things...)
namespace MDM
{
public static class Bootstrapper
{
private static AutofacDependencyResolver? Locator;
private static IContainer? Container;
public static void Register()
{
Splat.Locator.CurrentMutable.InitializeSplat();
Splat.Locator.CurrentMutable.InitializeReactiveUI();
Splat.Locator.CurrentMutable.RegisterConstant<IViewLocator>(new ViewLocator());
var builder = new ContainerBuilder();
builder.RegisterType<MainWindowView>().As<IViewFor<MainWindowViewModel>>().SingleInstance();
builder.RegisterType<EinstellungenView>().As<IViewFor<EinstellungenViewModel>>().SingleInstance();
builder.RegisterType<MainWindowViewModel>().AsSelf().SingleInstance();
builder.RegisterType<EinstellungenViewModel>().AsSelf().SingleInstance();
Locator = builder.UseAutofacDependencyResolver();
builder.RegisterInstance(Locator);
Locator.InitializeReactiveUI();
Splat.Locator.SetLocator(Locator);
Container = builder.Build();
Locator.SetLifetimeScope(Container);
}
public static T Resolve<T>() where T : class
{
return Container!.Resolve<T>();
}
}
}
While debugging the following line of code in my IViewLocator is never hit:
public IViewFor? ResolveView<T>(T viewModel, string? contract = null)
{
}
So my question is: What do I need to do while bootstrapping, to tell ReactiveUi to use my IViewLocator?
If you decide to drop Splat (the IoC container used by ReactiveUI) and use Autofac, then you must go with it, especially when registering services.
Once you have registered a custom IoC container (properly), you shouldn't use Splat anymore to resolve any dependencies. Although Splat will redirect service requests to the Autofac container, I recommend against mixing the APIs.
Don't use the Service Locator anti-pattern. The IoC container should not be distributed across the application. Neither as injected reference nor as static reference.
Use the Abstract Factory pattern instead.
For this reason,
IViewLocator.ResolveView
must use factories instead of the staticResolve
method that you have implemented in yourBootstrapper
.