c# - WPF, MVVM, Navigation, Keeping Dependency Injection In-Tact -


i have simple wpf application utilizes unity framework dependency injection. currently, trying simplify method navigation between views in mvvm pattern implementation; however, many of examples throughout stack overflow not take consideration dependency injection caveat.

i have 2 entirely separate views.

one, main acts main window content loaded (pretty typical; unnecessary content eliminated):

<window x:class="application.ui.main">     <grid background="white">         <contentcontrol content="{binding aproperty}"/>     </grid> </window> 

the constructor receives viewmodel via constructor injection (again, simple):

    public partial class main     {         private mainviewmodel _mainviewmodel;          public main (mainviewmodel mainviewmodel)         {             initializecomponent();             this.datacontext = _mainviewmodel = mainviewmodel;         }     } 

i have usercontrol, home, want "navigate" main window (i.e. set contentcontrol. it's constructor receives viewmodel via constructor injection in same way main does. equally simple:

public home(homeviewmodel homeviewmodel) {     initializecomponent();      // set data context:     this.datacontext = homeviewmodel; } 

the main problem, here, want enable constructor-based injection while maintaining pure mvvm implementation possible.

i in view-first camp of mvvm, can find discussion in these comments.

i have seen allusions idea of navigation based service; however, unsure if maintains separation of concerns strived mvvm. datatemplates require view constructors not take arguments , have read criticisms of datatemplates argue viewmodels should not participate in instantiation of views.

this solution (in opinion) straight wrong viewmodel becomes aware of view , relies on service viewmodel instantiaion makes real dependency injection resolve viewmodel , view dependencies impossible. issue evident in use of relaycommand in msdn article.

does navigation service maintains global, singleton-like reference main view make sense? acceptable main view expose method, e.g.:

public void setcontent(usercontrol usercontrol) { //... } 

that accessed service?

this articulation of motivations behind implementation of solution provided author. not provide code great code examples provided linked article. these are, of course, opinions represent amalgamation of research topic

no-container needed solution

rachel lim wrote great article, navigation mvvm, describes how take full advantage of wpf's datatemplates solve challenges presented mvvm navigation. lim's approach provides "best" solution greatly reduces need framework dependencies; however, there no "great" way solve problem.

the greatest objection rachel's approach in general view model becomes responsible - or, "defines" - it's own relationship view. lim's solution, minor objection 2 reasons (and nothing further justify other bad architectural decisions, described later):

1.) datatemplate relationship not enforced other xaml file, i.e. view models are, themselves, never directly aware of views nor vice versa, so, our view's constructor further simplified, take example home class constructor - without need reference view model:

public home() {     initializecomponent(); } 

2.) relationship expressed else, association between particular view , view model easy change.

an application should able function (model domain) sufficiently without prescribed view. ideal stems effort best decouple application's supporting architecture , foster further application of solid programming principles, dependency injection.

the xaml file - not third-party dependency container - becomes pivotal point resolution of relationship between view , view model (which, consequently, directly contradicts op).

dependency injection

an application should designed entirely agnostic of container , - better - implementation-specific information regarding service dependencies. allows "assign" (inject) services oblige contract (interface) various classes make meat of our applications' functionality.

this leaves 2 criteria "good design":

  1. application classes should able support variety of services perform same task, long oblige described contract.
  2. application classes should never aware of - or reference - container, if container unity, prism, or galasoft.

the second point of utmost importance , "rule" broken, commonly. "rule breaking" being inspiration behind original post.

the response navigation problem in many applications inject wrapped dependency injection container used make calls out of implementing class resolve dependencies. class knows container and, worse, has greater, more concrete knowledge of specifics needs in order perform operations (and might argue more difficult maintain).

any knowledge of dependency resolution container on part of view, view model, or model anti-pattern (you can read more justification statement elsewhere).

a written application relies on dependency injection function without dependency injection framework, i.e. resolve dependencies, manually, handwritten bootstrapper (though require great deal of careful work).

lim's solution enables "not need" reference container within implementation.

what should left constructors like:

// view: public home() { //... }   // view model  public homeviewmodel (somemodelclass somemodel, maybeaservice someservice) 

if 1 goal modularization , reusability, above achieves that, well. continue abstract out further ensuring passed-in dependencies contract fulfillments via interfaces.


Comments

Popular posts from this blog

php - Invalid Cofiguration - yii\base\InvalidConfigException - Yii2 -

How to show in django cms breadcrumbs full path? -

ruby on rails - npm error: tunneling socket could not be established, cause=connect ETIMEDOUT -