I don’t know anything about WPF or MVVM, but your question is mainly about how to extract material from a container without using a service locator (or container directly) everywhere, right? If so, I can show you an example.
The fact is that instead you are using a factory that uses a container inside. Thus, you actually use the container in only one place.
Note. I will use the WinForms example and it is not bound to a specific container (because, as I said, I don’t know WPF ... and I use Castle Windsor instead of NInject), but since your main question is not WPF / NInject specific, it should be easy for you to “migrate” my response to WFP / NInject.
factory is as follows:
public class Factory : IFactory { private readonly IContainer container; public Factory(IContainer container) { this.container = container; } public T GetStuff<T>() { return (T)container.Resolve<T>(); } }
The main form of your application gets this factory through the constructor installation:
public partial class MainForm : Form { private readonly IFactory factory; public MainForm(IFactory factory) { this.factory = factory; InitializeComponent();
The container is initialized when the application starts, and the main form is allowed (therefore, it gets the factory through constructor injection).
static class Program { static void Main() { var container = new Container(); container.Register<MainForm>(); container.Register<IFactory, Factory>(); container.Register<IYourRepository, YourRepository>(); Application.Run(container.Resolve<MainForm>()); } }
Now the main form can use factory to get material similar to your repository from the container:
var repo = this.factory.GetStuff<IYourRepository>(); repo.DoStuff();
If you have other forms and you want to use the factory from there, you just need to enter the factory in these forms, as in the main form, register additional forms at startup and open them from the main form using factory.
Is this what you wanted to know?
EDIT:
Ruben, of course, you're right. My mistake.
All the material in my answer was an old example of me lying somewhere, but I was in a hurry when I sent my answer and did not carefully read the context of my old example.
In my old example, the main form was specified from which you can open any other application form. This is what the factory was for, so you don’t need to inject every other form through the constructor injection into the main form.
Instead, you can use factory to open any new form:
var form = this.factory.GetStuff<IAnotherForm>(); form.Show();
Of course, you do not need a factory to get the repository from the form if the repository is passed to the form through constructor injection.
If your application consists of only a few forms, you do not need a factory at all, you can simply pass the forms through the constructor injection:
public partial class MainForm : Form { private readonly IAnotherForm form;