c# - How to handle dependency injection in a WPF/MVVM application -


i starting new desktop application , want build using mvvm , wpf.

i intending use tdd.

the problem don´t know how should use ioc container inject dependencies on production code.

suppose have folowing class , interface:

public interface istorage {     bool savefile(string content); }  public class storage : istorage {     public bool savefile(string content){         // saves file using streamwriter     } } 

and have class has istorage dependency, suppose class viewmodel or business class...

public class someviewmodel {     private istorage _storage;      public someviewmodel(istorage storage){         _storage = storage;     } } 

with can write unit tests ensure working properly, using mocks , etc.

the problem when comes use in real application. know must have ioc container links default implementation istorage interface, how may it?

for example, how if had following xaml:

<window      ... xmlns definitions ... >    <window.datacontext>         <local:someviewmodel />    </window.datacontext> </window> 

how can correctly 'tell' wpf inject dependencies in case?

also, suppose need instance of someviewmodel cs code, how should it?

i feel i´m lost in this, appreciate example or guidance of how best way handle it.

i familiar structuremap, i´m not expert. also, if there better/easier/out-of-the-box framework, please let me know.

thanks in advance.

i have been using ninject, , found it's pleasure work with. set in code, syntax straightforward , has documentation (and plenty of answers on so).

so goes this:

create view model, , take istorage interface constructor parameter:

class usercontrolviewmodel {     public usercontrolviewmodel(istorage storage)     {      } } 

create viewmodellocator property view model, loads view model ninject:

class viewmodellocator {     public usercontrolviewmodel usercontrolviewmodel     {         { return iockernel.get<usercontrolviewmodel>();} // loading usercontrolviewmodel automatically load binding istorage     } } 

make viewmodellocator application wide resource in app.xaml:

<application ...>     <application.resources>         <local:viewmodellocator x:key="viewmodellocator"/>     </application.resources> </application> 

bind datacontext of usercontrol corresponding property in viewmodellocator.

<usercontrol ...              datacontext="{binding usercontrolviewmodel, source={staticresource viewmodellocator}}">     <grid>     </grid> </usercontrol> 

create class inheriting ninjectmodule, set necessary bindings (istorage , viewmodel):

class iocconfiguration : ninjectmodule {     public override void load()     {         bind<istorage>().to<storage>().insingletonscope(); // reuse same storage every time          bind<usercontrolviewmodel>().toself().intransientscope(); // create new instance every time     } } 

initialize ioc kernel on application startup necessary ninject modules (the 1 above now):

public partial class app : application {            protected override void onstartup(startupeventargs e)     {         iockernel.initialize(new iocconfiguration());          base.onstartup(e);     } } 

i have used static iockernel class hold application wide instance of ioc kernel, can access when needed:

public static class iockernel {     private static standardkernel _kernel;      public static t get<t>()     {         return _kernel.get<t>();     }      public static void initialize(params ininjectmodule[] modules)     {         if (_kernel == null)         {             _kernel = new standardkernel(modules);         }     } } 

this solution make use of static servicelocator (the iockernel), regarded anti-pattern, because hides class' dependencies. difficult avoid sort of manual service lookup ui classes, since must have parameterless constructor, , cannot control instantiation anyway, cannot inject vm. @ least way allows test vm in isolation, business logic is.

if has better way, please share.

edit: lucky likey provided answer rid of static service locator, letting ninject instantiate ui classes. details of answer can seen here


Comments

Popular posts from this blog

javascript - Jquery show_hide, what to add in order to make the page scroll to the bottom of the hidden field once button is clicked -

javascript - Highcharts multi-color line -

javascript - Enter key does not work in search box -