1
votes

I need to pass an id to my viewmodel constructor. This id is external, it is passed to the webpage that contains the silverlight app. I am using the MVVM Light framework. I have seen several articles about passing parameters to the viewmodel, but in all of them the parameter is something that is global or that can be instantiated with no parameters. In my case I need a GUID id in the constructor of my viewmodel and it's passed from another app.

EDIT:

This is the code of the locator:

public class ViewModelLocator
{
    public static IUnityContainer Container
    {
        get;
        private set;
    }

    /// <summary>
    /// Initializes a new instance of the ViewModelLocator class.
    /// </summary>
    public ViewModelLocator(Guid id)
    {
        Container = new UnityContainer();
    }


    /// <summary>
    /// Cleans up all the resources.
    /// </summary>
    public static void Cleanup()
    {
        Container.Resolve<CautelaVM>().Cleanup();
    }


    #region Cautela Inventário

    public CautelaVM CautelaInventario
    {
        get
        {
            return Container.Resolve<CautelaVM>();
        }
    }

    #endregion
}

The locator is passed to the DataContext in the view like this:

DataContext="{Binding Source={StaticResource Locator}

EDIT 2:

Now it works. This is the code I added in the view ctor for registering the GUID to be used in the VM ctor:

ViewModel.ViewModelLocator.Container.RegisterType<CautelaVM>(new InjectionConstructor(id));
2
Why can't you use property injection? - dan
I'm not sure how to do that. Can you point me in the right direction? I'm not very experienced in silverlight and/or MVVM. - budahead
It's not mvvm related. You construct your object first and then set the guid using a property or an Initialize(Guid) method - dan
@dan with your insights I've been investigating on this and this is where I am, so far. My viewmodel has the Id property and I also have a RelayCommand that sets the Id. Now I am trying to bind this command to the onload of the view so that it sets the id of the viewmodel when it loads. I think this is where you were pointing me at. Now the problem is how to pass the parameter to the RelayCommand. The parameter id comes from the webpage that contains the silverlight. How do I get the id from the view to the viewmodel, still leaving both completly decoupled? - budahead
What about my answer? - dan

2 Answers

1
votes

Use a factory via the Typed Factory Facility. You'll define a factory interface like so:

public interface IFooViewModelFactory
{
    IFooViewModel Create(Guid guid);
}

Then add the facility to your Windsor configuration:

kernel.AddFacility<TypedFactoryFacility>();
kernel.Register(
                Component.For<IFooViewModelFactory>()
                         .AsFactory()
               );

Then rather than just resolving the IFooViewModel, you'll resolve IFooViewModelFactory and call Create:

public class MainViewModel
{
    readonly IFooViewModelFactory fooViewModelFactory;

    public MainViewModel(IFooViewModelFactory fooViewModelFactory)
    {
        this.fooViewModelFactory = fooViewModelFactory;
    }

    public IFooViewModel CreateFoo(Guid guid)
    {
        return fooViewModelFactory.Create(guid);
    }
}

Note that Windsor provides the implementation of the factory, not you. Also, the factory matches parameters in the constructor with the Create method parameters by name, so make sure your FooViewModel constructor matches, e.g.:

public class FooViewModel
{
    // "Guid guid" matches IFooViewModelFactory.Create(Guid guid)
    public FooViewModel(Guid guid)
    {
        // ...
    }
}
1
votes

If you are using MVVM light and the ViewModelLocator you can pass the GUID to it. Once the locator knows the GUID you can register it with the SimpleIoc and use it as a dependency.