3

I use the following code

 Splat.Locator.Current.GetService(...) 

to get view for view model. But this method allows to use only one view for one view model. But I have to show 1 data (view model) in multiple views. Is it possible by Splat.Locator?

Brian
  • 25,523
  • 18
  • 82
  • 173
  • 2
    Instead of changing the title to say SOLVED, please mark one of the answers as accepted; then we'll know that you got a solution to your problem. – Eric Lippert Sep 05 '19 at 21:46

2 Answers2

4

The Register() and GetService() have a contract argument, which you can use as a key to get the implementation you need.

Example, where "giveMeBar"/"giveMeBaz" are values for the contract argument:

using System;
using Splat;

namespace ConsoleApp1
{
    internal class Program
    {
        private static void Main()
        {
            // Register
            Locator.CurrentMutable.Register(() => new Bar(), typeof(IFoo), "giveMeBar");
            Locator.CurrentMutable.Register(() => new Baz(), typeof(IFoo), "giveMeBaz");

            // Resolve
            var bar = Locator.Current.GetService<IFoo>("giveMeBar");
            var baz = Locator.Current.GetService<IFoo>("giveMeBaz");

            // Which types did we get?
            Console.WriteLine(bar);
            Console.WriteLine(baz);
            Console.ReadLine();

            // Outputs:
            // ConsoleApp1.Bar
            // ConsoleApp1.Baz
        }        
    }

    internal interface IFoo { }
    internal class Bar : IFoo { }
    internal class Baz : IFoo { }
}
Magnus
  • 353
  • 3
  • 8
  • 3
    There is also some attributes that the view model locators can use that specify the view contract for resolution. https://github.com/reactiveui/ReactiveUI/blob/eb53eee4bd1865b3a226ec468c0a344620349bee/src/ReactiveUI/View/ViewContractAttribute.cs#L17 – Glenn Watson Sep 04 '19 at 15:35
  • 1
    Neat! Haven't seen an example of using that attribute though. Kent Boogart has an example of using contracts in [the sample code](https://github.com/kentcb/YouIandReactiveUI/blob/master/Host.WPF/Views/Samples/Chapter%2015/Sample%2002/MainView.xaml.cs) for [his book.](https://kent-boogaart.com/you-i-and-reactiveui/) Notice the ViewModel.ViewMode selects which view is used. – Magnus Sep 04 '19 at 18:06
  • 1
    OK. Thank you. I saw this attribute earlier, but i do not know, how it can helps me: in my app Splat.Locator.Current.GetService(...) is called from ViewLocator.ResolveView(T viewModel, string contract = null) by ReactiveUI assembly when i call Router.Navigate or ViewModelViewHost is shown. And parameter "contract" is always null or "landscape". But now i found properties ViewModelViewHost.ViewContract, ViewModelViewHost.ViewContractObservable and RoutedViewHost.ViewContractObservable, and now i can specify contracts for different ViewModelViewHost's and RoutedViewHost's. – Alexander Kalenteenkov Sep 05 '19 at 21:35
2

I don’t think this is possible because Locator will get confused when you navigate using ViewModel first so it will always instantiate latest view your associated with ViewModel. My suggestion maybe you create that ViewModel as base class and create another ViewModel which inherit that ViewModel and then assign it in Splat.Locator like usual

albilaga
  • 419
  • 1
  • 10
  • 26