I'd like to use Dependency Injection in a scenario where I have to inject resources into GUI-controls. As that might be the wrong Place, I have some reasons to do it here and not in a view model (eg. I need Window handles and such).
Constructor parameter injection seems to be the preferred way. As most of you know WPF controls must have a parameter-less constructors, otherwise the XAML does not work and for the current scenario I love to keep my XAML since it contains some name registrations and bindings.
So: How can I use constructor-DI in a WPF+XAML scenario and (if possible in the case of Simple Injector)?
Does a Markup extension exist or can the XAML parser be made Container-Aware and accept parameter-having constructors as controls?
Scheme example:
<Grid>
<gg:WhateverResourceNeedingViewer ItemSource={Binding Items}/>
</Grid>
And:
public class WhateverResourceNeedingViewer : ItemsControl
{
public WhateverResourceNeedingViewer(Dep1 d, DepResource d2)
{
...
}
...
}
It is good practice to not only build your viewmodels using the SOLID design principles but to do this in your views also. The usage of usercontrols can help you with this.
Downside of the approach you're suggesting, if technically possible, is that this design will violate SRP and OCP.
SRP because all dependencies your usercontrol needs must be injected in the consuming window/view while this view probably does not need (all of) these dependencies.
And OCP because every you add or delete a dependency from your usercontrol you also need to add or delete this from the consuming window/view.
With usercontrols you're able to compose the view just as you compose your other classes like services, command- and queryhandlers, etc. When it comes to dependency injection the place for composing your application is the composition root
ContentControls in WPF are all about 'composing' your view from other 'content' in your application.
A MVVM tool like Caliburn Micro typically uses contentcontrols to inject a usercontrol view (read: xaml without code behind) with it's own viewmodel. As a matter of fact, when using a MVVM you would build all views in the application from the usercontrols class, as a best practice.
This could look something like this:
And the XAML for the MainView:
The result will be that the
MainView
is displayed in a window where theDataContext
of that window is set to theMainViewModel
. The contentcontrol will be filled with theUserControlView
with itsDataContext
set to theUserControlViewModel
class. This automagically happens because the MVVM tool will bind the viewmodels to corresponding views using Convention over configuration.If you don't use a MVVM tool but directly inject your dependencies in the code behind of your window class you simply can follow the same pattern. Use a ContentControl in your view, just as the above example and inject the
UserControl
(with a constructor containing parameters as you wish) in the constructor of the window. Then just set theContent
property of the ContentControl to the injected instance of your UserControl.That would look like:
This may be considered an anti-pattern - on a number of levels - (see Ric's answer for details) but if you just want to get this working, wish to be pragmatic and have a simple use-case, I would suggest a static DI resolver. This comes in super handy for legacy components or situations like this where one is constrained by the underlying architecture.
Usage, from your example: