0

I have a complex business object, which I create at user login, and need to persist it throughout most viewmodels of the application. What I can do is send it with the messenger each time I create a new viewmodel, that works, but it's too much code, which is all the same every time, and I believe it is not a correct way of doing things. What I did in windows forms - I had all forms inherit from a base class, that has this business object as a member, and is included in constructor. I believe, SimpleIoc may be used for the problem. Well, here how to use MVVMLight SimpleIoc? I've fouond an indication that a concrete object may be registered (but for the interface - why?). So, is there a way to store an object in the container throughout the lifetime of an application? And it has parameters in constructor if this is important.

Community
  • 1
  • 1
Eugene Bykov
  • 133
  • 8
  • According to the author of MVVMLight, it is possible: http://stackoverflow.com/questions/7297014/does-the-mvvm-light-simpleioc-support-singletons – Fayilt Jan 30 '14 at 13:04

1 Answers1

1

As it states in the linked tutorial

2) Every object is a singleton by default. To resolve an object so that it's not a singleton you need to pass a unique value to the GetInstance call:

SimpleIoc.Default.GetInstance<MainViewModel>(Guid.NewGuid().ToString());

So to get the same instance each time you pass nothing (or always the same value) to the call to GetInstance

[Test]
public void CreateNonGeneric_ReturnsSameInstance1()
{
    SimpleIoc.Default.Register<Repository>();

    var result1 = SimpleIoc.Default.GetInstance<Repository>();
    var result2 = SimpleIoc.Default.GetInstance<Repository>();

    Assert.That(result1, Is.SameAs(result2));
}

[Test]
public void CreateNonGeneric_ReturnsSameInstance2()
{
    SimpleIoc.Default.Register<IRepository, Repository>();

    var result1 = SimpleIoc.Default.GetInstance<IRepository>();
    var result2 = SimpleIoc.Default.GetInstance<IRepository>();

    Assert.That(result1, Is.SameAs(result2));
}

[Test]
public void CreateNonGeneric_ReturnsSameInstance3()
{
    SimpleIoc.Default.Register<Repository>();

    var result1 = SimpleIoc.Default.GetInstance<Repository>("alwaysthesame");
    var result2 = SimpleIoc.Default.GetInstance<Repository>("alwaysthesame");

    Assert.That(result1, Is.SameAs(result2));
}

UPDATE

You can configure the dependencies during the registration. Here's one with a string

[Test]
public void RegisterSingletonWithFunc_GetIstance_ReturnsSameInstanceEachTime()
{
    SimpleIoc.Default.Register<IRepository, Repository>();
    SimpleIoc.Default.Register<Repository>(() => 
        new Repository("dependency"), "single");
    var result1 = SimpleIoc.Default.GetInstance<IRepository>("single");
    var result2 = SimpleIoc.Default.GetInstance<IRepository>("single");

    Assert.That(result1, Is.SameAs(result2));
}

And here's one with a dependency that is created by SimpleIoc

[Test]
public void RegisterSingletonWithDependentClass_GetIstance_ReturnsSame()
{
    SimpleIoc.Default.Register<IRepository, Repository>();
    SimpleIoc.Default.Register<SomeService>();
    SimpleIoc.Default.Register<Repository>(() => 
        new Repository(
            SimpleIoc.Default.GetInstance<SomeService>())
            , "single");
    var result1 = SimpleIoc.Default.GetInstance<IRepository>("single");
    var result2 = SimpleIoc.Default.GetInstance<IRepository>("single");

    Assert.That(result1, Is.SameAs(result2));
}
Community
  • 1
  • 1
qujck
  • 14,388
  • 4
  • 45
  • 74
  • To build the business object I cannot use the default parameterless constructor, I need to pass certain values, in certain cases complex business objects themselves. Thus, I cannot just register a class name for the container. It needs to be my very object, or I need to pass parameters somehow in class registration. – Eugene Bykov Jan 31 '14 at 05:52
  • 1
    Thank you! Your update helped me to achieve exactly what I was looking for! – Eugene Bykov Jan 31 '14 at 12:50