动态加载Silverlight应用的dll文件(可实现插件功能)(转)
http://www.pin5i.com/showtopic-17423.html
在Mike Taulty的视频教程中有一个动态加载silverlight应用程序的DEMO,其程序运行效果如下:
当加载dll之后:
其实实现这个的效果本身并不难,主要是这个DEMO的应用场景可以让人做很大的扩展,比如说插
件机制等.
好了,让我们看看如何实际去开发这个示例,以便让大家从流程和技术点上有个了解.
首先我们需要建立一个叫DynamicLoading的silverlight Application, 然后将如下的内容拷贝
到Page.xaml中:
- <UserControl x:Class="DynamicLoading.Page"
- xmlns="http://schemas.microsoft.com/client/2007"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- Width="400" Height="300">
- <Grid x:Name="LayoutRoot" Background="White">
- <Grid.RowDefinitions >
- <RowDefinition />
- <RowDefinition />
- </Grid.RowDefinitions>
- <StackPanel>
- <StackPanel>
- <TextBox Width="200" x:Name="txtPlugIn" Margin="10" Text="Implementation.dll" />
- </StackPanel>
- <Button HorizontalAlignment="Center" Margin="10" Width="96" Content="加载DLL"
- Click="OnClick" />
- </StackPanel>
- <Grid Grid.Row="1" Background="AliceBlue" Margin="20" x:Name="gridHosting">
- </Grid>
- <StackPanel VerticalAlignment="Bottom">
- <TextBlock x:Name="txtToEdit" FontSize="16" FontStyle="italic" Text="编辑内容"
- TextAlignment="center" HorizontalAlignment="Stretch" Grid.Row="2"
- VerticalAlignment="Center"/>
- </StackPanel>
- </Grid>
- </UserControl>
然后我们需要先建立一个接口文件(类似于插件接口),所以在当前SLN下新加一个Silverlight Class
Library 项目,名称为:Interfaces .将class.cs文件改名为:IEditText.cs .
将如下接口内容拷贝到该cs文件中:
- public class TextChangedEventArgs : EventArgs
- {
- public string Text { get; set; }
- }
- public interface IEditText
- {
- UIElement GetControls();
- void SetText(string text);
- event EventHandler<TextChangedEventArgs> TextChanged;
- }
编译这个接口项目.接下来我们将会实现这个接口(相当于实际的插件功能).
我们再新建一个叫Implementation的Silverlight Class Library 项目,重命名class.cs文件为Editor.cs
, 将如下内容拷贝到项目的cs文件中:
- public class Editor : Interfaces.IEditText
- {
- TextBox textBox;
- public Editor()
- {
- textBox = new TextBox();
- }
- //插件运行时加载的控件(界面)
- public UIElement GetControls()
- {
- StackPanel Panel = new StackPanel();
- StackPanel stackPanel = new StackPanel();
- stackPanel.Margin = new Thickness(5);
- stackPanel.Orientation = Orientation.Horizontal;
- textBox = new TextBox();
- textBox.Width = 300;
- textBox.Height = 70;
- Button button = new Button();
- button.Content = "点击这里";
- button.Click += OnButtonClick;
- button.Width = 60;
- stackPanel.Children.Add(textBox);
- Panel.Children.Add(stackPanel);
- Panel.Children.Add(button);
- return Panel;
- }
- public void SetText(string text)
- {
- textBox.Text = text;
- }
- //将点击提交按钮时,更新相应的界面内容
- void OnButtonClick(object sender, EventArgs args)
- {
- if (TextChanged != null)
- {
- TextChanged(this, new Interfaces.TextChangedEventArgs()
- {
- Text = textBox.Text
- });
- }
- }
- public event EventHandler<Interfaces.TextChangedEventArgs> TextChanged;
- }
之后,我们编译一下译项目.
下面看一下加载上面类库的代码(位于Page.xaml.cs文件中):
- public partial class Page : UserControl
- {
- public Page()
- {
- InitializeComponent();
- }
- //点击加载按钮事件
- void OnClick(object sender, EventArgs args)
- {
- //获取要加载的dll文件信息
- string assembly = txtPlugIn.Text;
- WebClient client = new WebClient();
- //准备获取dll文件的信息
- client.OpenReadCompleted += OnReadCompleted;
- client.OpenReadAsync(new Uri(assembly, UriKind.Relative));
- }
- void OnReadCompleted(object sender, OpenReadCompletedEventArgs e)
- {
- AssemblyPart part = new AssemblyPart();
- //获取加载的dll信息(stream格式)
- Assembly assembly = part.Load(e.Result);
- //构造该对象(插件)的实例
- IEditText editor =
- assembly.CreateInstance("Implementation.Editor") as IEditText;
- if (editor != null)
- { //加载其中的控件(gridHosting类型为<Grid>)
- gridHosting.Children.Add(editor.GetControls());
- editor.SetText(txtToEdit.Text);
- //完成事件绑定
- editor.TextChanged += OnTextChanged;
- }
- }
- //内容更新
- void OnTextChanged(object sender, Interfaces.TextChangedEventArgs e)
- {
- txtToEdit.Text = e.Text;
- }
- }
当然要编译还要引用一下前面写的接口项目(Interfaces),这样代码部分就完成了.这里我们还
要将类库Implementation.dll(插件)放入web项目中的ClientBin文件夹下.这样我们就可以运行文章
开始处的页面了.
是不是很简单,这里面主要的一块内容就是使用WebClient读取dll文件,如下:
- WebClient client = new WebClient();
- client.OpenReadCompleted += OnReadCompleted;
- client.OpenReadAsync(new Uri(assembly, UriKind.Relative));
其它的内容都是小Case:)
好了,今天的内容就到这里了,感兴趣的朋友可以一起来讨论:)
源码下载: