WPF/MVVM Navigation with child ViewModels having dependencies
I'm trying to use both MVVM and Dependency Injection pattern in my WPF MDI application.
I'm using VM first approach.
Basically, my app starts with the App.xaml.cs class which is supposed to be, if I understood the thing well, my composition root (where all dependencies are resolved). Here's a sample :
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
...
var login = new LoginView();
login.DataContext = new LoginViewModel(Dependency1, Dependency2);
loginView.ShowDialog();
if (loginView.DialogResult.GetValueOrDefault())
{
var app = new MainWindow();
var mainVM = new MainViewModel(Dependency3, Dependency4);
app.DataContext = mainVM;
app.Show();
}
}
}
No problem so far, I can resolve dependencies for both LoginViewModel and MainViewModel whether I use a DI container or Dependency Injection by hand. Now let's dig into MainViewModel.
I was inspired by Rachel Lim's approach and used a SelectedViewModel property to get/set the currently used ViewModel which is bound to its View using DataTemplates. I'll let you look at the link for more details on the process since it is quite unrelated to my issue here.
The important thing is that my MainViewModel is in charge of switching ViewModels when needed. But my children ViewModels have dependencies. Here's a simplified sample :
class MainViewModel
{
private ViewModel1 vm1;
private ViewModel2 vm2;
public MainViewModel(Dependency1, Dependency2)
{
...
}
...
// Method used by an ICommand to display the ViewModel1's associated View
private void DisplayView1()
{
vm1 = new ViewModel1(Dependency3, Dependency4, Dependency5);
// Method used by an ICommand to display the ViewModel2's associated View
private void DisplayView2()
{
vm2 = new ViewModel2(Dependency3, Dependency6);
SelectedViewModel = vm2;
}
...
}
As you can see, some dependencies are shared between several children ViewModels and some are not.
My problem is, I have trouble injecting those from the composition root. So far, I have found only two solutions :
- Having two composition root (kinda) : resolving LoginViewModel and MainViewModel in App.xaml.cs and children ViewModels in MainViewModel. This implicates, when using an IOC container, referencing the container in both classes.
- Passing children ViewModels as MainViewModel's constructor parameter and treat them like any other dependencies. My problem with this approach is that, if I have, let's say, ten ViewModels, the MainViewModel's constructor will become huge.
I read that one could pass a factory to the MainViewModel and delegate the responsibility to create the children ViewModels to it, but I didn't see any sample using children ViewModels with constructor parameters.
I don't understand how I could use this method without passing all children's dependencies to the MainViewModel's constructor and hence, without making it huge again.
Maybe there's something I don't see, but it seems like a deadend to me.
Please help me getting this right and show me the right direction.
Thanks.
wpf mvvm dependency-injection navigation inversion-of-control
|
show 5 more comments
I'm trying to use both MVVM and Dependency Injection pattern in my WPF MDI application.
I'm using VM first approach.
Basically, my app starts with the App.xaml.cs class which is supposed to be, if I understood the thing well, my composition root (where all dependencies are resolved). Here's a sample :
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
...
var login = new LoginView();
login.DataContext = new LoginViewModel(Dependency1, Dependency2);
loginView.ShowDialog();
if (loginView.DialogResult.GetValueOrDefault())
{
var app = new MainWindow();
var mainVM = new MainViewModel(Dependency3, Dependency4);
app.DataContext = mainVM;
app.Show();
}
}
}
No problem so far, I can resolve dependencies for both LoginViewModel and MainViewModel whether I use a DI container or Dependency Injection by hand. Now let's dig into MainViewModel.
I was inspired by Rachel Lim's approach and used a SelectedViewModel property to get/set the currently used ViewModel which is bound to its View using DataTemplates. I'll let you look at the link for more details on the process since it is quite unrelated to my issue here.
The important thing is that my MainViewModel is in charge of switching ViewModels when needed. But my children ViewModels have dependencies. Here's a simplified sample :
class MainViewModel
{
private ViewModel1 vm1;
private ViewModel2 vm2;
public MainViewModel(Dependency1, Dependency2)
{
...
}
...
// Method used by an ICommand to display the ViewModel1's associated View
private void DisplayView1()
{
vm1 = new ViewModel1(Dependency3, Dependency4, Dependency5);
// Method used by an ICommand to display the ViewModel2's associated View
private void DisplayView2()
{
vm2 = new ViewModel2(Dependency3, Dependency6);
SelectedViewModel = vm2;
}
...
}
As you can see, some dependencies are shared between several children ViewModels and some are not.
My problem is, I have trouble injecting those from the composition root. So far, I have found only two solutions :
- Having two composition root (kinda) : resolving LoginViewModel and MainViewModel in App.xaml.cs and children ViewModels in MainViewModel. This implicates, when using an IOC container, referencing the container in both classes.
- Passing children ViewModels as MainViewModel's constructor parameter and treat them like any other dependencies. My problem with this approach is that, if I have, let's say, ten ViewModels, the MainViewModel's constructor will become huge.
I read that one could pass a factory to the MainViewModel and delegate the responsibility to create the children ViewModels to it, but I didn't see any sample using children ViewModels with constructor parameters.
I don't understand how I could use this method without passing all children's dependencies to the MainViewModel's constructor and hence, without making it huge again.
Maybe there's something I don't see, but it seems like a deadend to me.
Please help me getting this right and show me the right direction.
Thanks.
wpf mvvm dependency-injection navigation inversion-of-control
1
You're trying to do all the DI stuff yourself, you need to bring in a DI container such as unity, mef, Autofac or something else. Unity is a standard one supported by the .NET framework, here's a link to a start to finish tutorial: accusoft.com/blog/… If you use a DI container you set it up with all the dependencies in this and simply resolve the object needed, in your case ViewModel1 & ViewModel2 in the MainViewModel's constructor.
– Coops
Nov 22 '18 at 16:42
Actually, I do use a DI container (ninject). I leave it out of the sample on purpose since I read that a good dependency graph could be resolved regardless of using a container. So basically, what're saying is that my child ViewModels should be treated like MainViewModel's dependencies and hence injected in its constructor ?
– olhybrius
Nov 22 '18 at 17:22
Excellent stuff, you need to inject all your objects and get them resolving from the container then. I've not used ninject but I'm guessing that it supports Constructor Injection. If you change the Constructor of the MainViewModel to take ViewModel1 & ViewModel2 as paramters then your DI container will resolve them and all their depedencies for you. It's the DI containers job to worry about dependencies, you just need the instance of the ViewModel injected where you want it.
– Coops
Nov 22 '18 at 17:25
Thanks for your answers. But isn't this a problem if my MainViewModel has like 10 childs ? Isn't this too much dependencies/constructor parameters for a single class ?
– olhybrius
Nov 22 '18 at 17:28
If your MainViewModel takes ViewModel1-10 then so be it...have them resolved by the container. The whole idea of IOC is that you don't do the actual construction of objects. To reduce things you could create a factory class that creates the ViewModel1-10 and then all you need to do is inject the factory. Then in your code factory.CreateViewModelX and it'll return one for you.
– Coops
Nov 22 '18 at 17:31
|
show 5 more comments
I'm trying to use both MVVM and Dependency Injection pattern in my WPF MDI application.
I'm using VM first approach.
Basically, my app starts with the App.xaml.cs class which is supposed to be, if I understood the thing well, my composition root (where all dependencies are resolved). Here's a sample :
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
...
var login = new LoginView();
login.DataContext = new LoginViewModel(Dependency1, Dependency2);
loginView.ShowDialog();
if (loginView.DialogResult.GetValueOrDefault())
{
var app = new MainWindow();
var mainVM = new MainViewModel(Dependency3, Dependency4);
app.DataContext = mainVM;
app.Show();
}
}
}
No problem so far, I can resolve dependencies for both LoginViewModel and MainViewModel whether I use a DI container or Dependency Injection by hand. Now let's dig into MainViewModel.
I was inspired by Rachel Lim's approach and used a SelectedViewModel property to get/set the currently used ViewModel which is bound to its View using DataTemplates. I'll let you look at the link for more details on the process since it is quite unrelated to my issue here.
The important thing is that my MainViewModel is in charge of switching ViewModels when needed. But my children ViewModels have dependencies. Here's a simplified sample :
class MainViewModel
{
private ViewModel1 vm1;
private ViewModel2 vm2;
public MainViewModel(Dependency1, Dependency2)
{
...
}
...
// Method used by an ICommand to display the ViewModel1's associated View
private void DisplayView1()
{
vm1 = new ViewModel1(Dependency3, Dependency4, Dependency5);
// Method used by an ICommand to display the ViewModel2's associated View
private void DisplayView2()
{
vm2 = new ViewModel2(Dependency3, Dependency6);
SelectedViewModel = vm2;
}
...
}
As you can see, some dependencies are shared between several children ViewModels and some are not.
My problem is, I have trouble injecting those from the composition root. So far, I have found only two solutions :
- Having two composition root (kinda) : resolving LoginViewModel and MainViewModel in App.xaml.cs and children ViewModels in MainViewModel. This implicates, when using an IOC container, referencing the container in both classes.
- Passing children ViewModels as MainViewModel's constructor parameter and treat them like any other dependencies. My problem with this approach is that, if I have, let's say, ten ViewModels, the MainViewModel's constructor will become huge.
I read that one could pass a factory to the MainViewModel and delegate the responsibility to create the children ViewModels to it, but I didn't see any sample using children ViewModels with constructor parameters.
I don't understand how I could use this method without passing all children's dependencies to the MainViewModel's constructor and hence, without making it huge again.
Maybe there's something I don't see, but it seems like a deadend to me.
Please help me getting this right and show me the right direction.
Thanks.
wpf mvvm dependency-injection navigation inversion-of-control
I'm trying to use both MVVM and Dependency Injection pattern in my WPF MDI application.
I'm using VM first approach.
Basically, my app starts with the App.xaml.cs class which is supposed to be, if I understood the thing well, my composition root (where all dependencies are resolved). Here's a sample :
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
...
var login = new LoginView();
login.DataContext = new LoginViewModel(Dependency1, Dependency2);
loginView.ShowDialog();
if (loginView.DialogResult.GetValueOrDefault())
{
var app = new MainWindow();
var mainVM = new MainViewModel(Dependency3, Dependency4);
app.DataContext = mainVM;
app.Show();
}
}
}
No problem so far, I can resolve dependencies for both LoginViewModel and MainViewModel whether I use a DI container or Dependency Injection by hand. Now let's dig into MainViewModel.
I was inspired by Rachel Lim's approach and used a SelectedViewModel property to get/set the currently used ViewModel which is bound to its View using DataTemplates. I'll let you look at the link for more details on the process since it is quite unrelated to my issue here.
The important thing is that my MainViewModel is in charge of switching ViewModels when needed. But my children ViewModels have dependencies. Here's a simplified sample :
class MainViewModel
{
private ViewModel1 vm1;
private ViewModel2 vm2;
public MainViewModel(Dependency1, Dependency2)
{
...
}
...
// Method used by an ICommand to display the ViewModel1's associated View
private void DisplayView1()
{
vm1 = new ViewModel1(Dependency3, Dependency4, Dependency5);
// Method used by an ICommand to display the ViewModel2's associated View
private void DisplayView2()
{
vm2 = new ViewModel2(Dependency3, Dependency6);
SelectedViewModel = vm2;
}
...
}
As you can see, some dependencies are shared between several children ViewModels and some are not.
My problem is, I have trouble injecting those from the composition root. So far, I have found only two solutions :
- Having two composition root (kinda) : resolving LoginViewModel and MainViewModel in App.xaml.cs and children ViewModels in MainViewModel. This implicates, when using an IOC container, referencing the container in both classes.
- Passing children ViewModels as MainViewModel's constructor parameter and treat them like any other dependencies. My problem with this approach is that, if I have, let's say, ten ViewModels, the MainViewModel's constructor will become huge.
I read that one could pass a factory to the MainViewModel and delegate the responsibility to create the children ViewModels to it, but I didn't see any sample using children ViewModels with constructor parameters.
I don't understand how I could use this method without passing all children's dependencies to the MainViewModel's constructor and hence, without making it huge again.
Maybe there's something I don't see, but it seems like a deadend to me.
Please help me getting this right and show me the right direction.
Thanks.
wpf mvvm dependency-injection navigation inversion-of-control
wpf mvvm dependency-injection navigation inversion-of-control
edited Nov 22 '18 at 20:26
olhybrius
asked Nov 22 '18 at 10:52
olhybriusolhybrius
12
12
1
You're trying to do all the DI stuff yourself, you need to bring in a DI container such as unity, mef, Autofac or something else. Unity is a standard one supported by the .NET framework, here's a link to a start to finish tutorial: accusoft.com/blog/… If you use a DI container you set it up with all the dependencies in this and simply resolve the object needed, in your case ViewModel1 & ViewModel2 in the MainViewModel's constructor.
– Coops
Nov 22 '18 at 16:42
Actually, I do use a DI container (ninject). I leave it out of the sample on purpose since I read that a good dependency graph could be resolved regardless of using a container. So basically, what're saying is that my child ViewModels should be treated like MainViewModel's dependencies and hence injected in its constructor ?
– olhybrius
Nov 22 '18 at 17:22
Excellent stuff, you need to inject all your objects and get them resolving from the container then. I've not used ninject but I'm guessing that it supports Constructor Injection. If you change the Constructor of the MainViewModel to take ViewModel1 & ViewModel2 as paramters then your DI container will resolve them and all their depedencies for you. It's the DI containers job to worry about dependencies, you just need the instance of the ViewModel injected where you want it.
– Coops
Nov 22 '18 at 17:25
Thanks for your answers. But isn't this a problem if my MainViewModel has like 10 childs ? Isn't this too much dependencies/constructor parameters for a single class ?
– olhybrius
Nov 22 '18 at 17:28
If your MainViewModel takes ViewModel1-10 then so be it...have them resolved by the container. The whole idea of IOC is that you don't do the actual construction of objects. To reduce things you could create a factory class that creates the ViewModel1-10 and then all you need to do is inject the factory. Then in your code factory.CreateViewModelX and it'll return one for you.
– Coops
Nov 22 '18 at 17:31
|
show 5 more comments
1
You're trying to do all the DI stuff yourself, you need to bring in a DI container such as unity, mef, Autofac or something else. Unity is a standard one supported by the .NET framework, here's a link to a start to finish tutorial: accusoft.com/blog/… If you use a DI container you set it up with all the dependencies in this and simply resolve the object needed, in your case ViewModel1 & ViewModel2 in the MainViewModel's constructor.
– Coops
Nov 22 '18 at 16:42
Actually, I do use a DI container (ninject). I leave it out of the sample on purpose since I read that a good dependency graph could be resolved regardless of using a container. So basically, what're saying is that my child ViewModels should be treated like MainViewModel's dependencies and hence injected in its constructor ?
– olhybrius
Nov 22 '18 at 17:22
Excellent stuff, you need to inject all your objects and get them resolving from the container then. I've not used ninject but I'm guessing that it supports Constructor Injection. If you change the Constructor of the MainViewModel to take ViewModel1 & ViewModel2 as paramters then your DI container will resolve them and all their depedencies for you. It's the DI containers job to worry about dependencies, you just need the instance of the ViewModel injected where you want it.
– Coops
Nov 22 '18 at 17:25
Thanks for your answers. But isn't this a problem if my MainViewModel has like 10 childs ? Isn't this too much dependencies/constructor parameters for a single class ?
– olhybrius
Nov 22 '18 at 17:28
If your MainViewModel takes ViewModel1-10 then so be it...have them resolved by the container. The whole idea of IOC is that you don't do the actual construction of objects. To reduce things you could create a factory class that creates the ViewModel1-10 and then all you need to do is inject the factory. Then in your code factory.CreateViewModelX and it'll return one for you.
– Coops
Nov 22 '18 at 17:31
1
1
You're trying to do all the DI stuff yourself, you need to bring in a DI container such as unity, mef, Autofac or something else. Unity is a standard one supported by the .NET framework, here's a link to a start to finish tutorial: accusoft.com/blog/… If you use a DI container you set it up with all the dependencies in this and simply resolve the object needed, in your case ViewModel1 & ViewModel2 in the MainViewModel's constructor.
– Coops
Nov 22 '18 at 16:42
You're trying to do all the DI stuff yourself, you need to bring in a DI container such as unity, mef, Autofac or something else. Unity is a standard one supported by the .NET framework, here's a link to a start to finish tutorial: accusoft.com/blog/… If you use a DI container you set it up with all the dependencies in this and simply resolve the object needed, in your case ViewModel1 & ViewModel2 in the MainViewModel's constructor.
– Coops
Nov 22 '18 at 16:42
Actually, I do use a DI container (ninject). I leave it out of the sample on purpose since I read that a good dependency graph could be resolved regardless of using a container. So basically, what're saying is that my child ViewModels should be treated like MainViewModel's dependencies and hence injected in its constructor ?
– olhybrius
Nov 22 '18 at 17:22
Actually, I do use a DI container (ninject). I leave it out of the sample on purpose since I read that a good dependency graph could be resolved regardless of using a container. So basically, what're saying is that my child ViewModels should be treated like MainViewModel's dependencies and hence injected in its constructor ?
– olhybrius
Nov 22 '18 at 17:22
Excellent stuff, you need to inject all your objects and get them resolving from the container then. I've not used ninject but I'm guessing that it supports Constructor Injection. If you change the Constructor of the MainViewModel to take ViewModel1 & ViewModel2 as paramters then your DI container will resolve them and all their depedencies for you. It's the DI containers job to worry about dependencies, you just need the instance of the ViewModel injected where you want it.
– Coops
Nov 22 '18 at 17:25
Excellent stuff, you need to inject all your objects and get them resolving from the container then. I've not used ninject but I'm guessing that it supports Constructor Injection. If you change the Constructor of the MainViewModel to take ViewModel1 & ViewModel2 as paramters then your DI container will resolve them and all their depedencies for you. It's the DI containers job to worry about dependencies, you just need the instance of the ViewModel injected where you want it.
– Coops
Nov 22 '18 at 17:25
Thanks for your answers. But isn't this a problem if my MainViewModel has like 10 childs ? Isn't this too much dependencies/constructor parameters for a single class ?
– olhybrius
Nov 22 '18 at 17:28
Thanks for your answers. But isn't this a problem if my MainViewModel has like 10 childs ? Isn't this too much dependencies/constructor parameters for a single class ?
– olhybrius
Nov 22 '18 at 17:28
If your MainViewModel takes ViewModel1-10 then so be it...have them resolved by the container. The whole idea of IOC is that you don't do the actual construction of objects. To reduce things you could create a factory class that creates the ViewModel1-10 and then all you need to do is inject the factory. Then in your code factory.CreateViewModelX and it'll return one for you.
– Coops
Nov 22 '18 at 17:31
If your MainViewModel takes ViewModel1-10 then so be it...have them resolved by the container. The whole idea of IOC is that you don't do the actual construction of objects. To reduce things you could create a factory class that creates the ViewModel1-10 and then all you need to do is inject the factory. Then in your code factory.CreateViewModelX and it'll return one for you.
– Coops
Nov 22 '18 at 17:31
|
show 5 more comments
1 Answer
1
active
oldest
votes
I just realized I got this whole factory thing wrong up until now.
Actually, the DI container that I use, Ninject, has an extension which address the exact same issue I am having. This extension needs an interface containing the methods to create the required dependencies (the ViewModels in my case) and create the concrete factory behind the scenes. I was just misusing it, thinking I needed to pass all dependencies to the interface somehow while it can resolve the ViewModels itself since these are already registered in the container.
So now, all I have is a single composition root (my App.xaml.cs) where the container resolve the LoginViewModel and the MainViewModel. The latter has the factory interface as a dependency which is used to resolve all children ViewModels and is also resolved by the container. No extra reference to the container needed !
Thank you so much Coops for your help ! You definitly got me on the right track here !
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53429327%2fwpf-mvvm-navigation-with-child-viewmodels-having-dependencies%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
I just realized I got this whole factory thing wrong up until now.
Actually, the DI container that I use, Ninject, has an extension which address the exact same issue I am having. This extension needs an interface containing the methods to create the required dependencies (the ViewModels in my case) and create the concrete factory behind the scenes. I was just misusing it, thinking I needed to pass all dependencies to the interface somehow while it can resolve the ViewModels itself since these are already registered in the container.
So now, all I have is a single composition root (my App.xaml.cs) where the container resolve the LoginViewModel and the MainViewModel. The latter has the factory interface as a dependency which is used to resolve all children ViewModels and is also resolved by the container. No extra reference to the container needed !
Thank you so much Coops for your help ! You definitly got me on the right track here !
add a comment |
I just realized I got this whole factory thing wrong up until now.
Actually, the DI container that I use, Ninject, has an extension which address the exact same issue I am having. This extension needs an interface containing the methods to create the required dependencies (the ViewModels in my case) and create the concrete factory behind the scenes. I was just misusing it, thinking I needed to pass all dependencies to the interface somehow while it can resolve the ViewModels itself since these are already registered in the container.
So now, all I have is a single composition root (my App.xaml.cs) where the container resolve the LoginViewModel and the MainViewModel. The latter has the factory interface as a dependency which is used to resolve all children ViewModels and is also resolved by the container. No extra reference to the container needed !
Thank you so much Coops for your help ! You definitly got me on the right track here !
add a comment |
I just realized I got this whole factory thing wrong up until now.
Actually, the DI container that I use, Ninject, has an extension which address the exact same issue I am having. This extension needs an interface containing the methods to create the required dependencies (the ViewModels in my case) and create the concrete factory behind the scenes. I was just misusing it, thinking I needed to pass all dependencies to the interface somehow while it can resolve the ViewModels itself since these are already registered in the container.
So now, all I have is a single composition root (my App.xaml.cs) where the container resolve the LoginViewModel and the MainViewModel. The latter has the factory interface as a dependency which is used to resolve all children ViewModels and is also resolved by the container. No extra reference to the container needed !
Thank you so much Coops for your help ! You definitly got me on the right track here !
I just realized I got this whole factory thing wrong up until now.
Actually, the DI container that I use, Ninject, has an extension which address the exact same issue I am having. This extension needs an interface containing the methods to create the required dependencies (the ViewModels in my case) and create the concrete factory behind the scenes. I was just misusing it, thinking I needed to pass all dependencies to the interface somehow while it can resolve the ViewModels itself since these are already registered in the container.
So now, all I have is a single composition root (my App.xaml.cs) where the container resolve the LoginViewModel and the MainViewModel. The latter has the factory interface as a dependency which is used to resolve all children ViewModels and is also resolved by the container. No extra reference to the container needed !
Thank you so much Coops for your help ! You definitly got me on the right track here !
answered Nov 24 '18 at 6:59
olhybriusolhybrius
12
12
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53429327%2fwpf-mvvm-navigation-with-child-viewmodels-having-dependencies%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
You're trying to do all the DI stuff yourself, you need to bring in a DI container such as unity, mef, Autofac or something else. Unity is a standard one supported by the .NET framework, here's a link to a start to finish tutorial: accusoft.com/blog/… If you use a DI container you set it up with all the dependencies in this and simply resolve the object needed, in your case ViewModel1 & ViewModel2 in the MainViewModel's constructor.
– Coops
Nov 22 '18 at 16:42
Actually, I do use a DI container (ninject). I leave it out of the sample on purpose since I read that a good dependency graph could be resolved regardless of using a container. So basically, what're saying is that my child ViewModels should be treated like MainViewModel's dependencies and hence injected in its constructor ?
– olhybrius
Nov 22 '18 at 17:22
Excellent stuff, you need to inject all your objects and get them resolving from the container then. I've not used ninject but I'm guessing that it supports Constructor Injection. If you change the Constructor of the MainViewModel to take ViewModel1 & ViewModel2 as paramters then your DI container will resolve them and all their depedencies for you. It's the DI containers job to worry about dependencies, you just need the instance of the ViewModel injected where you want it.
– Coops
Nov 22 '18 at 17:25
Thanks for your answers. But isn't this a problem if my MainViewModel has like 10 childs ? Isn't this too much dependencies/constructor parameters for a single class ?
– olhybrius
Nov 22 '18 at 17:28
If your MainViewModel takes ViewModel1-10 then so be it...have them resolved by the container. The whole idea of IOC is that you don't do the actual construction of objects. To reduce things you could create a factory class that creates the ViewModel1-10 and then all you need to do is inject the factory. Then in your code factory.CreateViewModelX and it'll return one for you.
– Coops
Nov 22 '18 at 17:31