четверг, 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!

Комментариев нет: