Silverlight-MEF-DEMO-extended computer functionality

Source: Internet
Author: User

Managed extensibility framework (MEF) is launched under the Microsoft. NET Framework to improve the reusability of applications and components, and is used to maximize the reuse of components. Use MEF to enable statically compiled. Net ApplicationsProgramConvert to dynamic combination, which is a good way to create scalable applications, scalable frameworks, and Application Extensions. It will be published as a part of. NET Framework 4.0. Now, MEF will also be included in Silverlight 4.0.

 
How does MEF work? There are three steps:

• Export (output)
• Import (input)
• Compose (combination)
Let us briefly explain how MEF works. The core of MEF includes a catalog and a compositioncontainer. Category is used to discover extensions, while container is used to coordinate creation and sort dependencies. Each composite part provides one or more exports, and usually depends on one or more external services or import. Each part manages an instance and runs the program for the application.

 

The following is an example of a small extensible calculator to explain these three processes.

1. First download the MEF framework package, which will be included in Silverlight 4.0, but Microsoft has already made it open-source.
Http://www.codeplex.com/MEF
2. Create a Silverlight navigate application and add Assembly reference (system. componentmodel. Composition. dll in the mef_beta_2 \ bin \ SL directory)
Add two class files package. CS and packagecatalog. CS under the project. These files are not provided in the latest MEF version and are mainly used to load the xap package of Silverlight.
These two files are provided in the MEF framework sample (mef_beta_2 \ samples \ PictureViewer. common), change the access modifiers of these two classes to public, and pay attention to modifying the namespace after adding them.
3. Modify the home. CS class

Code

Using system;
Using system. net;
Using system. windows;
Using system. Windows. controls;
Using system. Windows. documents;
Using system. Windows. Ink;
Using system. Windows. input;
Using system. Windows. Media;
Using system. Windows. Media. animation;
Using system. Windows. shapes;
Using system. componentmodel. composition;
Using system. componentmodel;

Namespace mefdemo
{
// Delegate for updating the interface
Public Delegate void operatehandler (ioperate OP );

/// <Summary>
/// Producer interface
/// </Summary>
Public interface ioperate
{
Double OP (double left, double right );
String symbol {set; get ;}
String label {Get; set ;}
}

/// <Summary>
/// Add the iterator
/// </Summary>
[Export (typeof (ioperate)]
Public class addbutton: button, ioperate
{
[Import ("addbuttoncontract", allowrecomposition = true)]
Public String label {get {return this. content. tostring () ;}set {This. content = value ;}}

[Import ("addsybomcontract", allowrecomposition = true)]
Public String symbol {set; get ;}

[Import ("clickhandler")]
Public operatehandler clickaction {Get; set ;}

# Region ioperate Member

Public double OP (double left, double right)
{
Return left + right;
}

# Endregion

Public addbutton ()
{
This. Click + = (S, e) => clickaction (this );
}
}

/// <Summary>
/// Subtraction Operator
/// </Summary>
[Export (typeof (ioperate)]
Public class subbutton: button, ioperate
{
[Import ("subbuttoncontract", allowrecomposition = true)]
Public String label {get {return this. content. tostring () ;}set {This. content = value ;}}

[Import ("subsybomcontract", allowrecomposition = true)]
Public String symbol {set; get ;}

[Import ("clickhandler")]
Public operatehandler clickaction {Get; set ;}

# Region ioperate Member

Public double OP (double left, double right)
{
Return left-right;
}

# Endregion

Public subbutton ()
{
This. Click + = (S, e) => clickaction (this );
}
}

/// <Summary>
/// Provide a value for each worker attribute
/// </Summary>
Public class componentattributeprovider
{
[Export ("addbuttoncontract")]
Public String addlabel {get {return "add ";}}
[Export ("addsybomcontract")]
Public String addsymbol {get {return "+ ";}}
[Export ("subbuttoncontract")]
Public String sublabel {get {return "sub ";}}
[Export ("subsybomcontract")]
Public String subsymbol {get {return "-";}}
}
}
4. Modify home. XAML

Code

xmlns =" http://schemas.microsoft.com/winfx/2006/xaml/presentation "
xmlns: x =" http://schemas.microsoft.com/winfx/2006/xaml "
xmlns: D =" http://schemas.microsoft.com/expression/blend/2008 "xmlns: MC = "http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns: navigation = "CLR-namespace: system. windows. controls; Assembly = system. windows. controls. navigation "
MC: ignorable =" D "D: designwidth =" 640 "D: designheight = "480"
Title = "home"
style = "{staticresource pagestyle}">

<Navigation: page. Resources>
<Itemspaneltemplate X: Key = "itemspaneltemplate1">
<Stackpanel orientation = "horizontal" horizontalalignment = "center" verticalignment = "center"/>
</Itemspaneltemplate>
</Navigation: page. Resources>

<Grid X: Name = "layoutroot">
<Scrollviewer X: Name = "pagescrollviewer" style = "{staticresource pagescrollviewerstyle}">

<Stackpanel X: Name = "contentstackpanel" background = "black">
<Stackpanel orientation = "horizontal" width = "455" Height = "89" margin = ", 91,-30">
<Textbox X: Name = "leftnum" horizontalalignment = "Left" verticalignment = "center" width = "83" textwrapping = "Wrap"/>
<Textblock X: name = "symbol" width = "62" text = "+" textwrapping = "Wrap" fontsize = "24" foreground = "# fff80606" textalignment = "center" verticalalignment = "Center "horizontalalignment =" Left "/>
<Textbox X: Name = "rightnum" horizontalalignment = "Left" verticalignment = "center" width = "78" textwrapping = "Wrap"/>
<Textblock width = "64" text = "=" textwrapping = "Wrap" foreground = "# fff20808" fontsize = "21.333" textalignment = "center" verticalignment = "center" placement = "center ""Left"/>
<Textbox X: Name = "result" horizontalalignment = "Left" verticalignment = "center" width = "146" textwrapping = "Wrap"/>
</Stackpanel>
<ListBox X: Name = "operatelist" itemssource = "{binding}" itemspanel = "{staticresource itemspaneltemplate1}" Height = "99" background = "{X: null} "borderbrush =" {X: NULL} "/>
<Button X: Name = "dynamicloadbutton" Height = "40" width = "196" content = "dynamicloadoperate"/>
</Stackpanel>
</Scrollviewer>
</GRID>

</Navigation: Page>

5. Create operatorcomponent. CS

Code

Using system;
Using system. net;
Using system. windows;
Using system. Windows. controls;
Using system. Windows. documents;
Using system. Windows. Ink;
Using system. Windows. input;
Using system. Windows. Media;
Using system. Windows. Media. animation;
Using system. Windows. shapes;
Using system. componentmodel. composition;
Using system. componentmodel;

Namespace mefdemo
{
// Delegate for updating the interface
Public Delegate void operatehandler (ioperate OP );

/// <Summary>
/// Producer interface
/// </Summary>
Public interface ioperate
{
Double OP (double left, double right );
String symbol {set; get ;}
String label {Get; set ;}
}

/// <Summary>
/// Add the iterator
/// </Summary>
[Export (typeof (ioperate)]
Public class addbutton: button, ioperate
{
[Import ("addbuttoncontract", allowrecomposition = true)]
Public String label {get {return this. content. tostring () ;}set {This. content = value ;}}

[Import ("addsybomcontract", allowrecomposition = true)]
Public String symbol {set; get ;}

[Import ("clickhandler")]
Public operatehandler clickaction {Get; set ;}

# Region ioperate Member

Public double OP (double left, double right)
{
Return left + right;
}

# Endregion

Public addbutton ()
{
This. Click + = (S, e) => clickaction (this );
}
}

/// <Summary>
/// Subtraction Operator
/// </Summary>
[Export (typeof (ioperate)]
Public class subbutton: button, ioperate
{
[Import ("subbuttoncontract", allowrecomposition = true)]
Public String label {get {return this. content. tostring () ;}set {This. content = value ;}}

[Import ("subsybomcontract", allowrecomposition = true)]
Public String symbol {set; get ;}

[Import ("clickhandler")]
Public operatehandler clickaction {Get; set ;}

# Region ioperate Member

Public double OP (double left, double right)
{
Return left-right;
}

# Endregion

Public subbutton ()
{
This. Click + = (S, e) => clickaction (this );
}
}

/// <Summary>
/// Provide a value for each worker attribute
/// </Summary>
Public class componentattributeprovider
{
[Export ("addbuttoncontract")]
Public String addlabel {get {return "add ";}}
[Export ("addsybomcontract")]
Public String addsymbol {get {return "+ ";}}
[Export ("subbuttoncontract")]
Public String sublabel {get {return "sub ";}}
[Export ("subsybomcontract")]
Public String subsymbol {get {return "-";}}
}
}

 

6. Run. In this way, a simple generator is built, and the export and import are connected to each other like pipelines.
 

7. According to this design, interfaces must be separated if we want to expand them. Create a Silverlight classlibrary Project (named contractlibrary), which encapsulates all the extension interfaces and defines the import/export contract.
Now, migrate the interfaces in the operatorcomponent. CS class in the original project to the Library Project, and create the class file operatecontract. CS.

Code

Using system;
Using system. net;
Using system. windows;
Using system. Windows. controls;
Using system. Windows. documents;
Using system. Windows. Ink;
Using system. Windows. input;
Using system. Windows. Media;
Using system. Windows. Media. animation;
Using system. Windows. shapes;

Namespace contractlibrary
{
Public Delegate void operatehandler (ioperate OP );

/// <Summary>
/// Producer interface
/// </Summary>
Public interface ioperate
{
Double OP (double left, double right );
String symbol {set; get ;}
String label {Get; set ;}
}
}
After compilation, add a reference to the contractlibrary project in the Silverlight main project (mefdemo ).
8. Create a New Silverlight classlibrary Project (named staticextension). This project is the DLL we use for static extension.
A). Create our generator class in the project, addbutton. CS, subbutton. cs. (The Code remains unchanged ).
B). But be sure to add references to the contractlibrary project and references to the MEF framework set ).
C) add the global property configuration class (componentconfiguration. CS)
D). Delete componetoperater. CS.
E). Add a reference to staticextension.
 

9. OK. In this way, we can add more extension operations to the compiler.

10. The following is the work to add a new Multiplication operation.
Add a new class multiply. CS in staticextension

 

Code

Using system;
Using system. net;
Using system. windows;
Using system. Windows. controls;
Using system. Windows. documents;
Using system. Windows. Ink;
Using system. Windows. input;
Using system. Windows. Media;
Using system. Windows. Media. animation;
Using system. Windows. shapes;
Using system. componentmodel. composition;
Using contractlibrary;

Namespace staticextension
{
/// <Summary>
/// Multiplication Handler
/// </Summary>
[Export (typeof (ioperate)]
Public class multiplybutton: button, ioperate
{
[Import ("multiplybuttoncontract", allowrecomposition = true)]
Public String label {get {return this. content. tostring () ;}set {This. content = value ;}}

[Import ("multiplysybomcontract", allowrecomposition = true)]
Public String symbol {set; get ;}

[Import ("clickhandler")]
Public operatehandler clickaction {Get; set ;}

# Region ioperate Member

Public double OP (double left, double right)
{
Return left * right;
}

# Endregion

Public multiplybutton ()
{
This. Click + = (S, e) => clickaction (this );
}
}
}

 

11. The above is static loading, so now we use MEF to implement dynamic expansion handler. Dynamic Expansion of desktop programs is to dynamically load DLL, while for Silverlight web programs, xap packages are dynamically loaded.
Create a common Silverlight application (named dynamicextension ).

 
Deselect Add a test page that references the application.
1) Delete unnecessary files such as app and main, and leave only one blank Silverlight project to reduce the size of the xap package.
2). Add contractlibrary and MEF framework set references (you can set the copylocal attribute of the referenced assembly to false because we have added and can reuse it in the main project)
3). Add division. CS.

Code

Using system;
Using system. net;
Using system. windows;
Using system. Windows. controls;
Using system. Windows. documents;
Using system. Windows. Ink;
Using system. Windows. input;
Using system. Windows. Media;
Using system. Windows. Media. animation;
Using system. Windows. shapes;
Using system. componentmodel. composition;
Using contractlibrary;

Namespace dynamicextension
{
/// <Summary>
/// Multiplication Handler
/// </Summary>
[Export (typeof (ioperate)]
Public class divisionbutton: button, ioperate
{
[Import ("divisionbuttoncontract", allowrecomposition = true)]
Public String label {get {return this. content. tostring () ;}set {This. content = value ;}}

[Import ("divisionsybomcontract", allowrecomposition = true)]
Public String symbol {set; get ;}

[Import ("clickhandler")]
Public operatehandler clickaction {Get; set ;}

# Region ioperate Member

Public double OP (double left, double right)
{
Return left * right;
}

# Endregion

Public divisionbutton ()
{
This. Click + = (S, e) => clickaction (this );
}
}
}

 

4) Add the configuration class componentconfiguration. CS

Code

Using system;
Using system. net;
Using system. windows;
Using system. Windows. controls;
Using system. Windows. documents;
Using system. Windows. Ink;
Using system. Windows. input;
Using system. Windows. Media;
Using system. Windows. Media. animation;
Using system. Windows. shapes;
Using system. componentmodel. composition;

Namespace dynamicextension
{
/// <Summary>
/// Configure the attribute value for each executor
/// </Summary>
Public class componentconfiguration
{
[Export ("divisionbuttoncontract")]
Public String addlabel {get {return "Div ";}}
[Export ("divisionsybomcontract")]
Public String addsymbol {get {return "/";}}
}
}

 
5). Modify home. CS to register related events and callbacks for the downloaded package.

1.
Code

Using system;
Using system. windows;
Using system. Windows. controls;
Using system. Windows. Navigation;
Using system. Collections. objectmodel;
Using system. componentmodel. Composition. Hosting;
Using system. reflection;
Using system. componentmodel. composition;
Using contractlibrary;

Namespace mefdemo
{
Public partial class home: Page
{
[Importmany (typeof (ioperate), allowrecomposition = true)]
Public observablecollection <ioperate> operates = new observablecollection <ioperate> ();

[Export ("clickhandler")]
Public operatehandler clickhandler {get {return operatebutton_click ;}}

Private packagecatalog Catalog;

/// <Summary>
/// This interface control is used to respond to some updates after calculation.
/// </Summary>
/// <Param name = "operate"> receiver </param>
Public void operatebutton_click (ioperate operate)
{
Try
{
Symbol. Text = operate. symbol;
Double left = double. parse (leftnum. Text );
Double right = double. parse (rightnum. Text );
This. Result. Text = operate. OP (left, right). tostring ();
}
Catch (exception E)
{
Childwindow errorwin = new errorwindow (E );
Errorwin. Show ();
}
}

Public home ()
{
Initializecomponent ();

This. Loaded + = new routedeventhandler (home_loaded );
// Register button event
This. dynamicloadbutton. Click + = (S, e) =>
{
// Download the package
Package. downloadpackageasync (
New uri ("dynamicextension. xap", urikind. Relative ),
(ARGs, package) => catalog. addpackage (Package)
);
// The package is automatically combined after it is added to packagecatalog.
// Re-input data to the import Loader with the allowrecomposition = true attribute added
};
}

void home_loaded (Object sender, routedeventargs e)
{< br> // combines all parts in the current xap package (parts)
catalog = new packagecatalog ();
catalog. addpackage (package. current);
compositioncontainer Container = new compositioncontainer (Catalog);
container. composeparts (this);

// After the combination, all operators implementing the operation interface (ioperate) will be automatically filled into the operates set.
// Bind the timer to The ListBox control for rendering.
This. operatelist. datacontext = operates;
}

// Executes when the user navigates to this page.
Protected override void onnavigatedto (navigationeventargs E)
{
}

}
}

 

OK, the final interface.
 
Click dynamicloadoperate.
 

There are still a lot of details in the program. For a theoretical introduction, refer to the documentation on msdn and codeplex.

ArticleSource: feino Network (www.firnow.com): http://dev.firnow.com/course/4_webprogram/asp.net/netjs/20100714/442928.html

 

Related Article

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.