MVVM mode: ViewModel Factory and injection

Source: Internet
Author: User

 

For the following reasons, ViewModel also requires multiple and needs to be injected:

 

1: different data needs to be provided for the View at design time and runtime.

 

To put it simply, data needs to be simulated during design. Interface Design developers need to bind (including support for Expression Blend binding) to do some simple processing. At the same time, because the simulation data is provided, the UI staff can better design the actual interface.

 

2: To facilitate Unit Testing

 

In most cases, ViewModel is combined into the Service class that provides the Service. In a simple application, we can inject a Service class MOCK for unit testing. If so, we can avoid providing multiple viewmodels. However, in some applications, such as Silverlight applications, services are provided by WerbService and WCF, and the interface classes supported by client application services are not allowed, and the client code is automatically generated, in this way, we need to provide multiple viewmodels to support unit testing.

 

3: provide simulated data for Design

 

Considering that there need to be multiple VMS, the ui vm needs to have a base class. Assuming that my UI needs to display a list of students, my VM base class is designed as follows:

 

View sourceprint? Public class MainPageVmBase

 

{

 

Public MainPageVmBase ()

 

{

 

Click = new DelegateCommand (OnClick );

 

}

 

 

 

Public IStudent StudentService {get; set ;}

 

Public IView View {get; set ;}

 

 

 

Private ICommand click;

 

 

 

Public ICommand Click

 

{

 

Get {return click ;}

 

Set {click = value ;}

 

}

 

 

 

Void OnClick (object arg)

 

{

 

View. Title = arg as string;

 

View. Show ();

 

}

 

 

 

Private List <Student> studets;

 

 

 

Public List <Student> Studets

 

{

 

Get {return studets ;}

 

Set {studets = value ;}

 

}

 

}

 

If the VM during design needs to provide analog data, the VM is:

 

View sourceprint? Public class MainPageVmMock: MainPageVmBase

 

{

 

Public MainPageVmMock ()

 

{

 

Studets = new List <Student> ()

 

{

 

New Student () {Name = "d1", Age = 11 },

 

New Student () {Name = "d2", Age = 22}

 

};

 

}

 

}

 

To explicitly simulate data during design, we need to use a DesignHelpers class (this class comes from the https://github.com/jeremiahredekop ):

 

View sourceprint? Public static class DesignHelpers

 

{

 

Private static bool? _ DesignMode;

 

Public static bool DesignMode

 

{

 

Get

 

{

 

If (! _ DesignMode. HasValue)

 

{

 

# If! SILVERLIGHT

 

_ DesignMode = new bool? (DesignerProperties. GetIsInDesignMode (new System. Windows. DependencyObject ()));

 

# Else

 

_ IsInDesignMode = new bool? (DesignerProperties. IsInDesignTool );

 

# Endif

 

}

 

Return _ designMode. Value;

 

}

 

}

 

}

 

With the processing of this class, we can explicitly simulate data when Expression Blend is bound:

 

 

4: ViewModel FACTORY

 

The VM bound to each UI actually comes from the vm factory class. On the page above, we are bound to the ViewModel attribute in MainPageVmFactory. Each VmFactory also has its own base class, as shown below:

 

View sourceprint? Public class ViewModelFactory <TViewModelRealBase>

 

Where TViewModelRealBase: class, new ()

 

{

 

Public TViewModelRealBase ViewModel

 

{

 

Get;

 

Set;

 

}

 

}

 

MainPageVmFactory is as follows:

 

View sourceprint? Public class MainPageVmFactory: ViewModelFactory <MainPageVmBase>

 

{

 

Public MainPageVmFactory ()

 

{

 

If (DesignHelpers. DesignMode = true)

 

{

 

This. ViewModel = new MainPageVmMock ();

 

}

 

Else

 

{

 

Using (IUnityContainer container = new UnityContainer ())

 

{

 

Var section = (UnityConfigurationSection) ConfigurationManager. GetSection ("unity ");

 

Section. Configure (container, "containerOne ");

 

This. ViewModel = container. Resolve <MainPageVmBase> ("MainPageVmReal ");

 

}

 

}

 

}

 

}

 

We can see that the VM at runtime is obtained through the unity injection method. As mentioned at the beginning of this article, the injection method is used for the convenience of unit testing. The injection is the MainPageVmReal type, which contains the service class that actually provides data, as follows:

 

View sourceprint? Public class MainPageVmReal: MainPageVmBase

 

{

 

Public MainPageVmReal ()

 

{

 

// Studets = new List <Student> ()

 

//{

 

// New Student () {Name = "r1", Age = 11 },

 

// New Student () {Name = "r2", Age = 22}

 

//};

 

Using (IUnityContainer container = new UnityContainer ())

 

{

 

UnityConfigurationSection section = (UnityConfigurationSection) ConfigurationManager. GetSection ("unity ");

 

Section. Configure (container, "containerOne ");

 

IStudent service = container. Resolve <IStudent> ("StudentService ");

 

Studets = service. GetAllStudent () as List <Student>;

 

}

 

}

 

}

 

In MainPageVmReal, the actual data service class can be the client code of WCF, or anything else. This is not the focus of our attention, so we don't have to worry about the injection code in it.

 

Running result:

 

 

5: Injection

 

Injection is easy to understand. Writing in the configuration requires the VM type:

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.