My application is growing in complexity.
Currently, I have a collection of classes that make up a "Backend", this contains a DataInterface that talks to a database and returns POCO classes, a ModelProvider that wraps them up in models, and a ViewModelProvider that creates views, all dependent on each other.
These instances are created on application start-up, and then wrapped up in a single "Backend" class. There's only one instance of this for the application. I'm finding many, many classes need to carry around this Backend instance to function.
I also have a class "AppController" which controls the high level navigation, and things like showing dialogues.
As a result, these two classes are passed around in constructors for nearly every ViewModel that's going to be doing anything complected.
This just doesn't seem sensible for me, but it must be a very common problem having a couple of single-instance classes that need to be accessed all over the application.
I was thinking one solution would be to make a single, static, class (say the already existing "backend" class) that could keep track of this, so all I need to do is:
StaticBackend.ViewModelProvider.GetSomeViewModelsForMe();
Is this good practice, or is there a more established way of doing it?
Dependency injection:
I'm trying to get my head around dependency injection. It looks like I'm not far off if I start creating interfaces for the ModelProvider, ViewModelProvider etc.
This seems like I would be in a similar place, except things might be formally more sensible, I'd still have to 'inject' IModelProvider, and IViewModelProvider classes all the way through from constructor to constructor.
So this is how things are at like at the moment (but encapsulating some of the back-end into interfaces):
interface INavagationManager
{
void NavagateTo(Page page);
}
interface IViewModelProvider
{
void CreateSomeViewModelsToDisplay();
}
class HomePage : Page
{
INavagationManager NavagationManager;
IViewModelProvider ViewModelProvider;
//this contains no dependencies on the IViewModelProvider, but it does with INavagationManager
public HomePage(INavagationManager navagationManager, IViewModelProvider viewModelProvider) {
this.NavagationManager = navagationManager;
//this is "injected" but it's not really a dependency of HomePage, as it never wants to get ViewModels, but the pages it creates do
this.ViewModelProvider = viewModelProvider;
}
public void UserWantsToNavagateSomewhere()
{
//all ViewModelProvider exists for is to be passed on down the 'chain'
NavagationManager.NavagateTo(new SubPage(ViewModelProvider));
}
}
class SubPage : Page
{
IViewModelProvider ViewModelProvider;
List<MyViewModel> MyViewModels;
public SubPage(IViewModelProvider viewModelProvider)
{
ViewModelProvider = viewModelProvider;
//actually use this dependency for something
MyViewModels = ViewModelProvider.CreateSomeViewModelsToDisplay();
}
}
Using interfaces makes it easier to do UnitTesting in future, because I can feed it mock INavagationManager etc to test behavior. But I'm still in much the same position I was in before, I'm still a little confused at how IoC containers fit.
It seems, I'd create a Container, which deals with injecting dependencies like the IViewModelProvider and INavagationManager in the above example, and I'd instead pass the Container between all the objects? Like this:
interface INavagationManager
{
void NavagateTo(Page page);
}
interface IViewModelProvider
{
void CreateSomeViewModelsToDisplay();
}
class HomePage : Page
{
Container Container;
INavagationManager NavagationManager;
//this contains no IViewModelProvider, but in instance of Container
public HomePage(Container container, IViewModelProvider viewModelProvider) {
this.NavagationManager = navagationManager;
this.Container= container;
}
public void UserWantsToNavagateSomewhere()
{
//all ViewModelProvider exists for is to be passed on down the 'chain'
NavagationManager.NavagateTo(Container.GetInstance<SubPage>());
}
}
class SubPage : Page
{
IViewModelProvider ViewModelProvider;
List<MyViewModel> MyViewModels;
public SubPage(IViewModelProvider viewModelProvider)
{
ViewModelProvider = viewModelProvider;
//actually use this dependency for something
MyViewModels = ViewModelProvider.CreateSomeViewModelsToDisplay();
}
}