Search code examples
c#wpfmvvm-lightservice-locatorsimpleioc

SimpleIOC with MVVMlight register and use


Hi i try to register my class into serviceLocator and reuse it my code is:

public ViewModelLocator()
{
    ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

    SimpleIoc.Default.Register<IUnitOfWork, UnitOfWork>(true);

    SimpleIoc.Default.Register<MainViewModel>(() =>
    {
        return new MainViewModel(UnitOfWorkItem);
    });
    SimpleIoc.Default.Register<LoginViewModel>(() =>
    {
        return new LoginViewModel(UnitOfWorkItem);
    });
}

public UnitOfWork UnitOfWorkItem
{
    get
    {
        return ServiceLocator.Current.GetInstance<UnitOfWork>();
    }
}

public MainViewModel Main
{
    get
    {
        return ServiceLocator.Current.GetInstance<MainViewModel>();
    }
}

when i try to give UnitOfWorkItem into the function that instance MainViewModel throw a exception like:

Type not found in cache: Client.Business.UnitOfWork.

my stack trace is:

in GalaSoft.MvvmLight.Ioc.SimpleIoc.DoGetService(Type serviceType, String key, Boolean cache) in D:\GalaSoft\mydotnet\MVVMLight\source\GalaSoft.MvvmLight\GalaSoft.MvvmLight.Extras (PCL)\Ioc\SimpleIoc.cs:riga 537 in GalaSoft.MvvmLight.Ioc.SimpleIoc.GetInstanceTService in D:\GalaSoft\mydotnet\MVVMLight\source\GalaSoft.MvvmLight\GalaSoft.MvvmLight.Extras (PCL)\Ioc\SimpleIoc.cs:riga 912 in PrivateVideoChat.Client.ViewModel.ViewModelLocator.get_UnitOfWorkItem() in C:\Users\c.fasolin\Documents\Visual Studio 2013\Projects\PrivateVideoChat.Solution\PrivateVideoChat.Client\ViewModel\ViewModelLocator.cs:riga 63 in PrivateVideoChat.Client.ViewModel.ViewModelLocator.<.ctor>b__0_1() in C:\Users\c.fasolin\Documents\Visual Studio 2013\Projects\PrivateVideoChat.Solution\PrivateVideoChat.Client\ViewModel\ViewModelLocator.cs:riga 52

Where I am wrong thanks


Solution

  • The UnitOfWorkItem property is looking for the registered UnitOfWork. But you never register anything with that class, you register the IUnitOfWork!

    You need to fix your UnitOfWorkItem by changing UnitOfWork into IUnitOfWork:

    public UnitOfWork UnitOfWorkItem
    {
        get
        {
            return ServiceLocator.Current.GetInstance<IUnitOfWork>();
        }
    }
    

    Even better:

    Just for your information, the power of an IoC container is that you can chain the registration. For example, in your case, your LoginViewModel and your MainViewModel require a UnitOfWork as constructor parameter.

    If you register both UnitOfWork, MainViewModel and LoginViewModel like this:

    SimpleIoc.Default.Register<UnitOfWork>(); 
    SimpleIoc.Default.Register<LoginViewModel>(); 
    SimpleIoc.Default.Register<MainViewModel>(); 
    

    The container will automatically provide to the ViewModels constructor the registred UnitOfWork and so on.

    This way you do not need to create a property getting the UnitOfWork for giving it to the LoginViewModel constructor.