动态加载Silverlight应用的dll文件(可实现插件功能)(转)

http://www.pin5i.com/showtopic-17423.html

 

在Mike Taulty的视频教程中有一个动态加载silverlight应用程序的DEMO,其程序运行效果如下:


    当加载dll之后:


  其实实现这个的效果本身并不难,主要是这个DEMO的应用场景可以让人做很大的扩展,比如说插
机制等.

  好了,让我们看看如何实际去开发这个示例,以便让大家从流程和技术点上有个了解.
  首先我们需要建立一个叫DynamicLoading的silverlight Application, 然后将如下的内容拷贝
到Page.xaml中:

  1. <UserControl x:Class="DynamicLoading.Page"
  2.     xmlns="http://schemas.microsoft.com/client/2007"
  3.     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.     Width="400" Height="300">
  5.     <Grid x:Name="LayoutRoot" Background="White">
  6.       <Grid.RowDefinitions >
  7.             <RowDefinition />
  8.             <RowDefinition />
  9.         </Grid.RowDefinitions>
  10.        
  11.       <StackPanel>
  12.           <StackPanel>   
  13.                 <TextBox Width="200" x:Name="txtPlugIn" Margin="10" Text="Implementation.dll" />
  14.           </StackPanel>
  15.             <Button HorizontalAlignment="Center" Margin="10" Width="96" Content="加载DLL"
  16.   Click="OnClick" />
  17.         </StackPanel>
  18.             <Grid  Grid.Row="1" Background="AliceBlue" Margin="20" x:Name="gridHosting">
  19.            
  20.             </Grid>
  21.         <StackPanel  VerticalAlignment="Bottom">
  22.             <TextBlock x:Name="txtToEdit" FontSize="16" FontStyle="italic"  Text="编辑内容"
  23.   TextAlignment="center" HorizontalAlignment="Stretch" Grid.Row="2"
  24.   VerticalAlignment="Center"/>
  25.         </StackPanel>
  26.     </Grid>
  27. </UserControl>
复制代码

然后我们需要先建立一个接口文件(类似于插件接口),所以在当前SLN下新加一个Silverlight Class
Library 项目,名称为:Interfaces .将class.cs文件改名为:IEditText.cs .
将如下接口内容拷贝到该cs文件中:

  1. public class TextChangedEventArgs : EventArgs
  2.     {
  3.         public string Text { get; set; }
  4.     }
  5.     public interface IEditText
  6.     {
  7.         UIElement GetControls();
  8.         void SetText(string text);
  9.         event EventHandler<TextChangedEventArgs> TextChanged;
  10.     }
复制代码

编译这个接口项目.接下来我们将会实现这个接口(相当于实际的插件功能).
我们再新建一个叫Implementation的Silverlight Class Library 项目,重命名class.cs文件为Editor.cs
, 将如下内容拷贝到项目的cs文件中:

  1. public class Editor : Interfaces.IEditText
  2. {
  3.     TextBox textBox;
  4.     public Editor()
  5.     {
  6.         textBox = new TextBox();
  7.     }
  8.     //插件运行时加载的控件(界面)
  9.     public UIElement GetControls()
  10.     {
  11.         StackPanel Panel = new StackPanel();
  12.         StackPanel stackPanel = new StackPanel();
  13.         stackPanel.Margin = new Thickness(5);
  14.         stackPanel.Orientation = Orientation.Horizontal;
  15.         textBox = new TextBox();
  16.         textBox.Width = 300;
  17.         textBox.Height = 70;
  18.         Button button = new Button();
  19.         button.Content = "点击这里";
  20.         button.Click += OnButtonClick;
  21.         button.Width = 60;
  22.         stackPanel.Children.Add(textBox);
  23.         Panel.Children.Add(stackPanel);
  24.         Panel.Children.Add(button);
  25.         return Panel;
  26.     }
  27.     public void SetText(string text)
  28.     {
  29.         textBox.Text = text;
  30.     }
  31.     //将点击提交按钮时,更新相应的界面内容
  32.     void OnButtonClick(object sender, EventArgs args)
  33.     {
  34.         if (TextChanged != null)
  35.         {
  36.             TextChanged(this, new Interfaces.TextChangedEventArgs()
  37.             {
  38.                 Text = textBox.Text
  39.             });
  40.         }
  41.     }
  42.     public event EventHandler<Interfaces.TextChangedEventArgs> TextChanged;
  43. }
复制代码

之后,我们编译一下译项目.

  下面看一下加载上面类库的代码(位于Page.xaml.cs文件中):

  1. public partial class Page : UserControl
  2. {
  3.     public Page()
  4.     {
  5.         InitializeComponent();
  6.     }
  7. //点击加载按钮事件
  8.     void OnClick(object sender, EventArgs args)
  9.     {
  10.         //获取要加载的dll文件信息
  11.         string assembly = txtPlugIn.Text;
  12.         WebClient client = new WebClient();
  13.         //准备获取dll文件的信息
  14.         client.OpenReadCompleted += OnReadCompleted;
  15.         client.OpenReadAsync(new Uri(assembly, UriKind.Relative));
  16.     }
  17.     void OnReadCompleted(object sender, OpenReadCompletedEventArgs e)
  18.     {
  19.         AssemblyPart part = new AssemblyPart();
  20.         //获取加载的dll信息(stream格式)
  21.         Assembly assembly = part.Load(e.Result);
  22. //构造该对象(插件)的实例
  23.         IEditText editor =
  24.             assembly.CreateInstance("Implementation.Editor") as IEditText;
  25.         if (editor != null)
  26.         {  //加载其中的控件(gridHosting类型为<Grid>)
  27.             gridHosting.Children.Add(editor.GetControls());
  28.             editor.SetText(txtToEdit.Text);
  29.             //完成事件绑定
  30.             editor.TextChanged += OnTextChanged;
  31.         }
  32.     }
  33.    
  34.     //内容更新
  35.     void OnTextChanged(object sender, Interfaces.TextChangedEventArgs e)
  36.     {
  37.         txtToEdit.Text = e.Text;
  38.     }
  39. }
复制代码

当然要编译还要引用一下前面写的接口项目(Interfaces),这样代码部分就完成了.这里我们还
要将类库Implementation.dll(插件)放入web项目中的ClientBin文件夹下.这样我们就可以运行文章
开始处的页面了.

  是不是很简单,这里面主要的一块内容就是使用WebClient读取dll文件,如下:

  1. WebClient client = new WebClient();
  2. client.OpenReadCompleted += OnReadCompleted;
  3. client.OpenReadAsync(new Uri(assembly, UriKind.Relative));
复制代码

其它的内容都是小Case:)

   好了,今天的内容就到这里了,感兴趣的朋友可以一起来讨论:)

源码下载:

dynamicloading.rar
posted @ 2011-12-15 14:26  董雨  阅读(223)  评论(0编辑  收藏  举报