Thursday, March 24, 2016

Connect View.DataContext to ViewModel: Prism vs BlackWidow vs. Fusion

BlackWidow requires Presenter<V,VM> follows naming convention to set DataCtx=VM. Fusion is
more explicit. Developer can select V,VM and Presenter during Asset Manager Design.
Prism is most explicit in that it either code or config V to VM setup. Since it does not
requires Presenter, View Composition requires register with Region to actually show View
after V DataContext set to VM.

(1) ViewModelLocator  --- Wire up using PropertyMetadata Event in DependProp

  //just as normal Dependency property declaration
public static readonly DependencyProperty AutoWireViewModelProperty =
     DependencyProperty.Register( "AutoWireViewModel", typeof(bool),
     typeof(VMLocators), new PropertyMetadata(false,OnChanged));

  // then create ViewModel as DataContext
  void OnChanged(DependencyObj d,PropChangedEventArgs e) {
    var vmType=d.GetType().FullName+"Model" //convention
    (FrameworkElement)d.DataContext = Activator.GetInstance(vmType);
}
usage in xmal
<UserControl ... local:VMLocators.AutoWireViewModel="true" >

(2) IVew/IViewModel -- Wire up through code-behind and DepInj
    Base Inteface
      IView { IVM ViewModel {get;set;} IViewModel {IV View {get;set;}}
    Derived Interface same code to allow Container.Reg different type
      IMWView : IView IMWViewModel : IViewModel 
    Implementation
      MWView :IMWView {
        public IViewModel { get { return (IMWViewModel) DataContext;}
                          set { DataContext =value;} }
      MWViewModel: IMWViewModel {
        public IView { get;set;}
        ctor(IMWView view) {View=view;
             View.ViewModel=this;//DI for VM ctor vs. Code-Behind V ctor

(3) IVew/IViewModel --- Wire up Code-Behind,View 1st
    Same as (2), except VM not see V, do not DI View into VM.

(4) IModule:Init() --- Trigger DI and View Composition
      _container.RegisterType(IMWView,MWView);
      _container.RegisterType(IMWViewModel,MWViewModel);
      _container.RegisterType(ToolbarView);
      _container.RegisterType(MWView);

      // replacing BlackWidow Activity by Discovery, Add in code anywhere
      _regMgr.RegisterViewWithRegion("mwReg",typeof(MWView));//Discovery

      vm1=_container.Resolve<IMWView>();
      vm2=_container.Resolve<IMWView>(); // more than 1 instance of VM.

    
      _regMgr.Regions["mwReg"].Add(vm1.View);
      IRegion r=_regMrg.Regions[""];

      r.Deactive(vm1.View); // swap out views
      regs.Add(vm2.View);

(5) MEF Wire-up
    Mef takes away the need to do Container.Reg/ResolveType so Add looks like
    _regMgr.Regions["mwReg"].Add(ServiceLocator.Current.GetInstanace<MWView>());

     [Export] public class MWView : UserControl  //DI by attribute
      ServiceLocator.Current.GetInstanace<MWView> triggers [Export]
   
    [ModuleExport(typeof(ModuleAModule),WhenAvailable)]
    public class ModuleAModule: IModule {
     [ImportingConstructor] ctor(IRegionManager)  //MEF DI Mgr
 
    IModule:Init() similar for _regMgr.Region[""].Add or IRegion.Add Deactivate
    But need to use ServiceLocator.Current.GetInstanace<T> in ServiceLocator.dll
    [Export][ModuleExport][ImportingCtor] are in System.CompMod.Composition


No comments:

Post a Comment