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.
Asked
Active
Viewed 917 times
0
-
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 Answers
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));
}
-
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
-
1Thank you! Your update helped me to achieve exactly what I was looking for! – Eugene Bykov Jan 31 '14 at 12:50