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

  在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:)

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

    源码下载请 点击这里:)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
1.概述 该组件提供类似ADO.NET编程接口,可以直接在Silverlight端访问Web端数据库。可以实现在Web端无需事先手工编写或自动创建任何程序代码和数据实体类的情况下, 便可在Silverlight端对Web端数据库进行增加、删除、修改、查询等数据操作。此外, 还支持访问数据库的存储过程(StoredProcdures)、视图(Views)、自定义函数(User Defined Functions)等。 2、使用前的准备 2.1组件Lib文件 该组件包含3个文件: System.Data.Silverlight.dll、 System.Data.Silverlight.Web.dll DataHandler.ashx 2.1.1System.Data.Silverlight.dll Silverlight端需引用的程序集,引用该程序集还需要引用关联的程序集,包含: System.ComponentModel.DataAnnotations.dll System.Windows.Controls.Data.dll System.Windows.Controls.Data.Input.dll System.Windows.Data.dll System.Xml.Linq.dll 该程序集中定义了一套DataSet、DataTa对象,作为数据通讯的数据格式,完全兼容ADO.NET中的DataSet、DataTable,两者之间可以通过XML互相转换,提供相应的转换方法。程序中还定义了一套DbConnection、DbCommand对象,用于向Web端发起数据库操作命令,使用方式类似ADO.NET。 2.1.2 System.Data.Silverlight.Web.dll Web服务器端文件,需要把该程序集拷贝到网站Bin目录,无需引用。 2.1.3 DataHandler.ashx Web服务器端的文件,需要把该文件拷贝到网站根目录。 2.2同步方式操作数据库示例 //创建一个数据连接 DbConnection conn = new DbConnection("Server=192.168.0.7;DataBase=JitonClient;Uid=sa;Pwd=jiton;"); //创建一个数据命令 DbCommandSyn cmd = new DbCommandSyn(); //设置命令的连接 cmd.Connection = conn; //设置SQL语句,可以是存储过程 cmd.CommandText = "SELECT [UserId],[UserName],[GroupId] FROM [Usertb] WHERE [GroupId]=@GroupId"; //设置命令类型,一般SQL语句是Text,存储过程是StoredProcedure cmd.CommandType = DbCommandType.Text; //设置执行类型 cmd.ExecuteType = DbExecuteType.Reader; //添加一个参数,无参数可以不添加 cmd.Parameters.Add(new DbParameter(DbType.Int32, "@GroupId", 5)); //执行命令,得到结果 DbCommandExecuteResult result = cmd.Execute(); if (!string.IsNullOrEmpty(result.ErrMsg))//首先判断ErrMsg是否有值,有表示执行过程发生错误 { MessageBox.Show("发生错误:" + result.ErrMsg); } else { DataTable dt = result.ReaderResult; //将数据显示在DataGrid中 this.dataGrid1.ItemsSource = dt.Rows; } 2.3异步方式操作数据库示例 //创建一个数据连接 DbConnection conn = new DbConnection("Data Source=|DataDirectory|CSmsPlatThird.db;Pooling=true;FailIfMissing=false"); //设置使用的数据访问程序集 conn.AssemblyName = "System.Data.SQLite"; //设置数据工厂,这里是SQLite的数据工厂 conn.DbProviderFactory = "System.Data.SQLite.SQLiteFactory"; //创建一个数据命令 DbCommandAsyn cmd = new DbCommandAsyn(); //设置命令的连接 cmd.Connection = conn; //设置SQL语句,可以是存储过程 cmd.CommandText = "SELECT [Id],[Content],[PlatFlag],[DateTime] FROM [T_Logger] WHERE [Id]>=@Id"; //设置命令类型,一般SQL语句是Text,存储过程是StoredProcedure cmd.CommandType = DbCommandType.Text; //设置执行类型 cmd.ExecuteType = DbExecuteType.Reader; //添加一个参数,无参数可以不添加 cmd.Parameters.Add(new DbParameter(DbType.Int32, "@Id", 3)); //设置命令执行完毕的委托事件 cmd.ExecuteEnd += new EventHandler<DbCommandExecuteResult>(cmd_ExecuteEnd); //异步执行命令 cmd.Execute(); void cmd_ExecuteEnd(object sender, DbCommandExecuteResult e) { if (!string.IsNullOrEmpty(e.ErrMsg))//首先判断ErrMsg是否有值,有表示执行过程发生错误 { MessageBox.Show("发生错误:" + e.ErrMsg); } else { DataTable dt = e.ReaderResult; //将数据显示在DataGrid中 this.dataGrid1.ItemsSource = dt.Rows; } } 2.4对其它数据库的支持 该组件默认支持SQL Sserver,理论上也可支持其它数据库,只要数据库提供对应的ADO.NET实现接口,已经测试过Access、SQLite。操作其它数据库时必须把对应的ADO.NET实现接口的程序集拷贝到网站Bin目录下面,操作SQL Server无需该步骤。比如操作SQLite数据库,需要把SQLite的ADO.NET实现接口程序集System.Data.SQLite.dll文件拷贝到网站Bin下面。此外还需指定DbConnection对象的AssemblyName、DbProviderFactory属性的值。 //创建一个数据连接 DbConnection conn = new DbConnection("Data Source=|DataDirectory|CSmsPlatThird.db;Pooling=true;FailIfMissing=false"); //设置使用的数据访问程序集 conn.AssemblyName = "System.Data.SQLite"; //设置数据工厂,这里是SQLite的数据工厂 conn.DbProviderFactory = "System.Data.SQLite.SQLiteFactory"; 其它操作步骤和操作SQL Server无差异,完整的示例代码见2.3中的示例。 2.5技术交流 有任何问题可以加入唯一指定的专用QQ群153079750进行反馈交流,也欢迎加入笔者的另一个Silverlight技术群175213051进行交流。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值