четверг, 28 августа 2008 г.

Dependency Injection in xaml

I want to describe a solution I've found to inject dependencies of my objects right in Xaml. This solution is special because it is coupled with CAB that I use as a platform for my smartclient applications, but I sincerely hope that you will see the idea behind particular implementation that will let you abstract this solution away from particular IoC framework.

Quite often I create objects in Xaml, and I'd like to follow the main principles of my development. As a part of this I'd like to inject dependencies in objects, being created by WPF, like I
do it in code-behind.



So I need a solution that will fit following requirements:

  • ability to be used in Binding;
  • ability to be used with POCO.
My solution consists of the same number of parts as abovementioned requirements:
  • IoCProvider - custom DataSourceProvider (Binding "knows" about DataSourceProvider and works with it perfectly);
  • a set of MarkupExtensions to be used with POCO;
IoCProvider

IoCProvider is the core of my solution. It is the part that infers dependencies by means of standard CAB IoC container - WorkItem.



Since
this object is created mostly by WPF engine, there is no way to inject a container into IoCProvider, but here we can use a well-known registry object, such as an Application object in WPF. Considering that my Application always implements IRootApplication interface, that is bound to publish root WorkItem, this task is no more a matter of interest (see IoCProvider constructor).

Main job in inferring of dependencies is done in BeginQuery method. One can initiate a query by calling a base
DataSourceProvider class Refresh() method manually, or it will be done automatically by means of Binding system.



Now we can use this provider as a source of data in Binding, but
attempts to bind POCO's property or field to requested dependency will cause an InvalidOperationException to be thrown, informing us that binding can be used only with Dependency Property. How do we escape this?

Markup Extension.

This is the solution for the second part - markup extension. Markup extensions can be used
almost everywhere in xaml. ServiceDependencyMarkupExtension is my example implementation, which infers WorkItem's service dependencies.



Below follows the result - we
inject our dependencies right in Xaml! Isn't it awesome?



I hope now you see how simple the dependency injection in xaml is, and I also hope you'd be able to make a step further and abstract the whole solution away from concrete IoC framework. You can see an example of such solution in Prism - its IContainerFacade interface.

Here is a couple of articles that will help you in process:
creating-a-custom-datasourceprovider
Injecting Xaml with Unity Application Block using Markup Extensions

Good luck!

среда, 6 августа 2008 г.

Kodama - a spirit of tree.

Some of you have probably read my post about Josh Smith and ViewModel coming to rescue people (WPF-addicted people, to be precise), just joking don't mind. In brief words, I wrote how ViewModel helped working with ComboBox or another Selector control to manage state of underlying CollectionView. After that I've generalized my thoughts, and there came a SelectorCollectionPresenter class, which made my sleep quiet. =) I'll publish code in the end as a bonus.


But now I want to write about the TreeView control, and how it can be united and simplified with ViewModel pattern. I was inspired a long time ago, when I read this article by Josh Smith, but had no time to work with WPF, solving other infrastructural problems, but I've got the idea stuck in my head.
And finally I got time to think about it and put it together in a reusable manner. As a result I've got a tree control with a spirit living in it. I named it Kodama, because kodama is a spirit from Japanese folklore, which is believed to live in trees. And the control itself was called KodamaView. As you might have already guessed, this spirit, which lives in my tree control, is nothing more than a ViewModel!

- he said ViewModel?

I want to warn everybody – I've just put together my thoughts on DM-V-VM pattern and Josh's fantastic ideas, so most of honors should go right to Josh!

KodamaView


KodamaView - is a UserControl, hosting a TreeView inside itself. In order to simulate TreeView's behavior, it inherits ITreeView interface, based on my IWPFView interface, and delegates all incoming calls to internal TreeView control.


TreeView simulating interface.


KodamaView control.


Control's xaml.

Kodama.

And now here are some words about Kodama.


Toriyama Sekien's illustration of a kodama appearing as an old man.

My Kodama (if it is allowed to say so) is an inheritor of ViewModel class, parameterized with ITreeView and IDataModelBase interfaces. The last one is made basic to be able to create Kodama with any derived DataModel class, because all of them embody this interface. DM is the source of data for the tree.



Every TreeViewItem gets its own ViewModel - a TreeViewItemViewModel.



TreeView is able to load child nodes "lazily", only when their parent node is expanded (I've borrowed the code from Josh's article, I hope he doesn't mind). All work on loading children is done in a LoadChildren method.



There is another one class in hierarchy - TreeViewItemViewModel`1. It has only one purpose to exist - to populate a typed Entity into the visual tree.



StructureTreeKodama is my example demonstrating this philosophy.




I remember, when I started the post, I've promised you a bonus. So here it is - SelectorCollectionPresenter class code. You can read some on details of it here.



Good luck!