How to use interception to simplify the design of model and viewmodel in mvvm

Source: Internet
Author: User

This article is a companion article titled "How to Use AOP to simplify model and viewmodel design in mvvm. Please read the previous article before reading this article. Otherwise, you may not have a deep understanding of the problem.

 

As mentioned in the previous article, we can use the AOP method. Specifically, we use a third-party framework (postsharp) to implementCodeInjection. The postsharp method is Static injection, which requires changing the Il code.

Please refer to the following. The IL code in the customer type has actually been changed. Postsharp changes the compilation behavior of Visual Studio.

 

Is there any other method besides this? Actually, I will introduce you to another PRACTICE IN THIS ARTICLE: Use the Interception Function (interception function provided by unity) in the Enterprise Library officially provided by Microsoft)

 

For introduction and download of Enterprise Library, visit the following address:

Http://entlib.codeplex.com/

This example is based on Enterprise Library 5.0.

 

Let's take a look at the example below. Suppose we have another model type called order, which indicates order. We hope that its code will be as concise as below.

  using  system;  namespace  wpfmvvmsample. models { Public   class  order: modelbase { Public   int  orderid {Get; set ;}  Public  datetime orderdate {Get; Set ;}}

[Note] Here we only inherit modelbase, and there is nothing special.

Please rest assured that we can do it. You only need to continue reading.

 

1. Add reference

We need to referenceProgramSet

 

2. Compile an interceptionbehavior

Behavior is an action we need to inject. This is a specialized term in interception.

[Note] This articleArticleFor more information about policy injection, see the instructions in Enterprise Library.

 

 Using System. LINQ; Using Microsoft. Practices. Unity. interceptionextension; Namespace Wpfmvvmsample { Public   Class Policypropertychangedbahavior: iinterceptionbehavior { Public System. Collections. Generic. ienumerable <system. type> getrequiredinterfaces (){ Return Enumerable. Empty <system. type> ();} Public Imethodreturn invoke (imethodinvocation input, getnextinterceptionbehaviordelegate getnext) {var result = getnext () (input, getnext ); // First execute the Method VaR methodname = input. methodbase. Name; var type = input. Target. GetType (); var targetmethod = type. getmethod ( "Onpropertychanged" , System. reflection. bindingflags. nonpublic | system. reflection. bindingflags. instance ); If (Methodname. startswith ( "Set _" ) & Targetmethod! = Null ) // Only inject this method. {Var propertyname = methodname. substring (4 ); // Parse the property name Targetmethod. Invoke (input. Target, New [] {Propertyname }); // Execute this method } Return Result ;} Public   Bool Willexecute {get { Return   True ;}}}}

[Note] the above code is very similar to the previous postsharp method, isn't it?

 

3. Modify the modelbase type

By default, Unity provides intercept and supports two main interceptors: transparentproxyinterceptor and virtualmethodinterceptor. We are going to use the first one here. It has a simple requirement, that is, the type to intercept, inheritanceMarshalbyrefobject

The code is modified as follows:

 

Using System; Using System. componentmodel; Using System. diagnostics; Namespace Wpfmvvmsample. Models { Public   Abstract   Class Modelbase: Marshalbyrefobject , Inotifypropertychanged { Public   Event Propertychangedeventhandler propertychanged; Protected   Void Onpropertychanged ( String Name ){If (Propertychanged! = Null ) Propertychanged ( This , New Propertychangedeventargs (name )); // To facilitate debugging, We output a line of information in the output window. Debug. writeline ( String . Format ( "{0} changed" , Name ));}}}
4. write code to implement interception and injection
 Using System; Using System. windows; Using Microsoft. Practices. Unity. interceptionextension; Namespace Wpfmvvmsample {/// <Summary>      /// Interaction logic for mainwindow. XAML      /// </Summary>      Public   Partial   Class Mainwindow: window { Public Mainwindow () {initializecomponent (); loaded + = New Routedeventhandler (mainwindow_loaded );} Void Mainwindow_loaded ( Object Sender, routedeventargs e) {var order = intercept. throughproxy ( New Models. Order (), New Transparentproxyinterceptor (), New [] { New Notifypropertychangedbahavior ()}); Order. orderdate = datetime. Now; order. orderid = 5 ;}}}
 
Please note that the Order instance cannot be created directly using the new method, but must be created using intercept.
 
 
 
Press F5 for debugging. We can also see the relevant message output in the output window. This indicates that the custom behavior is working, because it is the onpropertychanged method in the base class.
 
 
 
 
 
 
 
It is worth mentioning that, unlike postsharp, the interception we use here is dynamic interception and it will not modify our code. Please refer to the order code, which is the same as that in Visual Studio.
 
 
 
 
 

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.