4
votes

I'am using mvvm light SimpleIoC in a Xamarin project and use an instance key to get some view model.

SimpleIoc.Default.GetInstance<ContextViewModel>("contextIdentifier");

Is there a way to get this instance key in the instance itself like other dependencies, in constructor ?

I know i can create and set a custom property on my ContextViewModel but as my class need this value to work, i don't like the idea that i can get an "non-operationnal instance" of this view model.

Edit with more informations, to explain why i want my ViewModel instance know about its identifier :

It's a Xamarin.iOS application (ViewController are created by storyboard).

In my app, i have multiple instance of the same view controller (and in the same UITabBarController), and so, i need a different ViewModel instance for each view controller instance.

As my ViewModel need an id to get some data from database, I thought I would use this identifier also as instance identifier.

I can make it works by getting my ViewModel instance in the ViewDidLoad() method of my view controller, and call some Setters on it, but i don't like this (maybe i'm wrong :)) because in my mind, an IoC should only return operationnal instances (without needs of call multiple setters).

Best regards.

2
I don't understand what you are trying to do. Why should the instance know (and care) about its instance key?Fildor
Well, maybe i do wrong but in my app, i have multiple instance of the same view controller, and so, i need a different ViewModel instance for each view controller instance. As my ViewModel need an id to get some data from database, I thought I would use this identifier also as instance identifier.j-guyon
Ah, tricky ... Can you show how they are related? Does your ViewController class have a ViewModel field? How do you create your ViewController? I could imagine if you injected the viewmodel into the viewcontroller by ctor param, you could set a field in that ctor on the viewmodel, so it will be fully initialized when the controller becomes operational ... can you follow me?Fildor
I do , but i forgot to precise that this is a Xamarin.Ios application, so view controller are instanciated by storyboard. i update my question accordingly. thxj-guyon

2 Answers

1
votes

I don't think there is a way to access that ID in the constructor. That ID is registered internally in SimpleIOC. I would simply make a new type of ViewModel and add an InstanceID property to it.

var viewModel = SimpleIoc.Default.GetInstance<MyViewModel>("contextIdentifier");
viewModel.ID = "contextIdentifier";

public class MyViewModel : ViewModelBase
{
  public string ID { get; set; }
}
1
votes

It seems that it is not possible to get the instance id natively, so in order to be sure that my instance is fully operationnal, and avoid call setters in my ViewController, I finally add an interface to my view model and set the instance id directly in my ServiceLocator.

public interface IIdentifiableViewModel
{
    /// <summary>
    /// Gets or sets the instance key.
    /// </summary>
    /// <value>The instance key.</value>
    string InstanceKey { get; set; }
}

In the ServiceLocator :

public class ServiceLocator
{
    /// <summary>
    /// Gets the view model instance by key and pass it to the InstanceKey property
    /// </summary>
    /// <returns>The view model by key.</returns>
    /// <param name="key">Key.</param>
    /// <typeparam name="T">The 1st type parameter.</typeparam>
    public T GetViewModelByKey<T>(string key) where T : IIdentifiableViewModel
    {
        var vm = ServiceLocator.Current.GetInstance<T>(key);
        ((IIdentifiableViewModel)vm).InstanceKey = key;

        return vm;
    }

Feel free to answer if you have a more elegant or built-in solution.