构建一个.net Remoting 程序(真正的三层结构)

构建一个.net Remoting 程序(真正的三层结构)_突血推荐!!!

NET Remoting提供了一个功能强大、高效的处理远程对象的方法。我在开发一个电力软件时,由于业务量大,必须用三层结构。实现数据处理(浏览、更新)但是这方面的资料很少。通过摸索我找到的方法。谨献给想用.net开发三层结构数据库应用软件而又苦于找不到方法的C#程序员。




第一步:创建共享库

依次点击“文件”
->“新创建”->“工程”,选择创建一个C# Library,并将其命名为ydglServerLibrary,然后点击OK按钮。这将创建一个我们的.NET Remote客户端和服务器端用来通讯的“共享命令集”。

正面是完整的代码

using System;

using System.Runtime ;

using System.Data.OleDb;

using System.Data.SqlClient;

using System.Data;

 

using System.Configuration;

 

namespace ydglServerClassLibrary1

{

     
/// <summary>

     
/// Class1 的摘要说明。

     
/// </summary>


     
public class ydglDB:System.MarshalByRefObject 

     
{

         
private System.Data.OleDb.OleDbDataAdapter oleDbDataAdapter1;

         
private System.Data.OleDb.OleDbCommand oleDbSelectCommand1;

         
private System.Data.OleDb.OleDbCommand oleDbInsertCommand1;

         
private System.Data.OleDb.OleDbCommand oleDbUpdateCommand1;

         
private System.Data.OleDb.OleDbCommand oleDbDeleteCommand1;

         
private System.Data.OleDb.OleDbConnection oleDbConnection1;

         

         
private System.ComponentModel.Container components = null;

         

         

         

         
public void InitializeComponent()

         
{

              
this.oleDbDataAdapter1 = new System.Data.OleDb.OleDbDataAdapter();

              
this.oleDbSelectCommand1 = new System.Data.OleDb.OleDbCommand();

              
this.oleDbInsertCommand1 = new System.Data.OleDb.OleDbCommand();

              
this.oleDbUpdateCommand1 = new System.Data.OleDb.OleDbCommand();

              
this.oleDbDeleteCommand1 = new System.Data.OleDb.OleDbCommand();

              
this.oleDbConnection1 = new System.Data.OleDb.OleDbConnection();

              
// 

              
// oleDbDataAdapter1

              
// 

              
this.oleDbDataAdapter1.DeleteCommand = this.oleDbDeleteCommand1;

              
this.oleDbDataAdapter1.InsertCommand = this.oleDbInsertCommand1;

              
this.oleDbDataAdapter1.SelectCommand = this.oleDbSelectCommand1;

              
this.oleDbDataAdapter1.TableMappings.AddRange(new System.Data.Common.DataTableMapping[] {

                                                                                                                         
new System.Data.Common.DataTableMapping("Table""bm_gdfgs"new System.Data.Common.DataColumnMapping[] {

                                                                                                                                                                                                                                                       
new System.Data.Common.DataColumnMapping("code""code"),

                                                                                                                                                                                                                                                       
new System.Data.Common.DataColumnMapping("name""name")}
)}
);

              
this.oleDbDataAdapter1.UpdateCommand = this.oleDbUpdateCommand1;

              
// 

              
// oleDbSelectCommand1

              
// 

              
this.oleDbSelectCommand1.CommandText = "SELECT code, name FROM bm_gdfgs";

              
this.oleDbSelectCommand1.Connection = this.oleDbConnection1;

              
// 

              
// oleDbInsertCommand1

              
// 

              
this.oleDbInsertCommand1.CommandText = "INSERT INTO bm_gdfgs(code, name) VALUES (?, ?); SELECT code, name FROM bm_gdfgs W" +

                   
"HERE (code = ?)";

              
this.oleDbInsertCommand1.Connection = this.oleDbConnection1;

              
this.oleDbInsertCommand1.Parameters.Add(new System.Data.OleDb.OleDbParameter("code", System.Data.OleDb.OleDbType.VarChar, 2"code"));

              
this.oleDbInsertCommand1.Parameters.Add(new System.Data.OleDb.OleDbParameter("name", System.Data.OleDb.OleDbType.VarChar, 40"name"));

              
this.oleDbInsertCommand1.Parameters.Add(new System.Data.OleDb.OleDbParameter("Select_code", System.Data.OleDb.OleDbType.VarChar, 2"code"));

              
// 

              
// oleDbUpdateCommand1

              
// 

              
this.oleDbUpdateCommand1.CommandText = "UPDATE bm_gdfgs SET code = ?, name = ? WHERE (code = ?) AND (name = ? OR ? IS NUL" +

                   
"L AND name IS NULL); SELECT code, name FROM bm_gdfgs WHERE (code = ?)";

              
this.oleDbUpdateCommand1.Connection = this.oleDbConnection1;

              
this.oleDbUpdateCommand1.Parameters.Add(new System.Data.OleDb.OleDbParameter("code", System.Data.OleDb.OleDbType.VarChar, 2"code"));

              
this.oleDbUpdateCommand1.Parameters.Add(new System.Data.OleDb.OleDbParameter("name", System.Data.OleDb.OleDbType.VarChar, 40"name"));

              
this.oleDbUpdateCommand1.Parameters.Add(new System.Data.OleDb.OleDbParameter("Original_code", System.Data.OleDb.OleDbType.VarChar, 2, System.Data.ParameterDirection.Input, false, ((System.Byte)(0)), ((System.Byte)(0)), "code", System.Data.DataRowVersion.Original, null));

              
this.oleDbUpdateCommand1.Parameters.Add(new System.Data.OleDb.OleDbParameter("Original_name", System.Data.OleDb.OleDbType.VarChar, 40, System.Data.ParameterDirection.Input, false, ((System.Byte)(0)), ((System.Byte)(0)), "name", System.Data.DataRowVersion.Original, null));

              
this.oleDbUpdateCommand1.Parameters.Add(new System.Data.OleDb.OleDbParameter("Original_name1", System.Data.OleDb.OleDbType.VarChar, 40, System.Data.ParameterDirection.Input, false, ((System.Byte)(0)), ((System.Byte)(0)), "name", System.Data.DataRowVersion.Original, null));

              
this.oleDbUpdateCommand1.Parameters.Add(new System.Data.OleDb.OleDbParameter("Select_code", System.Data.OleDb.OleDbType.VarChar, 2"code"));

              
// 

              
// oleDbDeleteCommand1

              
// 

              
this.oleDbDeleteCommand1.CommandText = "DELETE FROM bm_gdfgs WHERE (code = ?) AND (name = ? OR ? IS NULL AND name IS NULL" +

                   
")";

              
this.oleDbDeleteCommand1.Connection = this.oleDbConnection1;

              
this.oleDbDeleteCommand1.Parameters.Add(new System.Data.OleDb.OleDbParameter("Original_code", System.Data.OleDb.OleDbType.VarChar, 2, System.Data.ParameterDirection.Input, false, ((System.Byte)(0)), ((System.Byte)(0)), "code", System.Data.DataRowVersion.Original, null));

              
this.oleDbDeleteCommand1.Parameters.Add(new System.Data.OleDb.OleDbParameter("Original_name", System.Data.OleDb.OleDbType.VarChar, 40, System.Data.ParameterDirection.Input, false, ((System.Byte)(0)), ((System.Byte)(0)), "name", System.Data.DataRowVersion.Original, null));

              
this.oleDbDeleteCommand1.Parameters.Add(new System.Data.OleDb.OleDbParameter("Original_name1", System.Data.OleDb.OleDbType.VarChar, 40, System.Data.ParameterDirection.Input, false, ((System.Byte)(0)), ((System.Byte)(0)), "name", System.Data.DataRowVersion.Original, null));

              
// 

              
// oleDbConnection1

              
// 

              
this.oleDbConnection1.ConnectionString = @"User ID=sa;Data Source=BILLGATES;Tag with column collation when possible=False;Initial Catalog=ydgl;Use Procedure for Prepare=1;Auto Translate=True;Persist Security Info=False;Provider=""SQLOLEDB.1"";Workstation ID=BILLGATES;Use Encryption for Data=False;Packet Size=4096";

              
// 

              
// Service1

              
// 

         

 

         }


         

         

         
public   DataSet Get_bm_gdfgs( )

         
{

              

              

              DataSet ds
=new DataSet( );

              oleDbDataAdapter1.Fill(ds);

            
return ds;

                   

         }


         
public DataSet Update_bm_gdfgs(DataSet ds)

         
{

              
if (ds!=null)

              
{

                   oleDbDataAdapter1.Update(ds);

                   
return ds;

              }


              
else

              
{

              
return null;

              }


         }


         

     }


}


 

请记住,如果得到System.Runtime.Remoting.Channels.Tcp名字空间不存在的信息,请检查是否象上面的代码那样添加了对System.Runtime.Remoting.dll的引用。

编译创建的工程,就会得到一个DLL文件,并可以在其他的工程中使用它。

第二步:创建Server对象

有几种方法可以创建Server对象,最直观的方法是下面的方法:在Visual Studio.NET中,依次点击“文件”
->“新创建”->“工程”,选择创建一个“Windows Application”,并将它命名为ydglServer。




最最重要的是,我们需要添加对刚才在第一步中所创建的DLL文件的应用,该应用程序才能正确地运行。依次点击“工程”
->“添加引用”,然后通过点击“浏览”按钮添加一个对在第一步中所创建的DLL文件的引用。

为了使用.NET remote功能,必须通过选择“工程”
->“添加引用”,添加对DLL文件的引用。在.NET标签中选择System.Runtime.Remoting.DLL,然后点击“OK”按钮。然后,需要象我们在第一步中那样添加对System.Runtime.Remoting.dll的引用。

下面的对象相当的简单和直观,我将就真正与.NET remoting相关的3行代码中的每一行进行解释。

TcpServerChannel是.NET remoting支持的二种信道类型中的一种,它将设置我们希望我们的对象对来自哪一个端口的请求进行回应,ChannelServices.RegisterChannel将把该端口号与操作系统中的TCP
/IP栈绑定。

TcpServerChannel channel 
= new TcpServerChannel(9932);
  ChannelServices.RegisterChannel(channel); 

另一种可以设置的信道类型是HTTP,只要简单地使用System.Runtime.Remoting.Channels.Http名字空间中的HttpServerChannel对象即可搞定。使用HTTP和TCP信道之间的区别可以简单的归结为:如果应用程序是在局域网上运行,则最好使用TCP信道,因为它的性能要好于HTTP信道;如果应用程序是在互联网上运行,则有时候根据防火墙的配置,HTTP是唯一的选择。需要记住的是,如果使用了防火墙软件,则防火墙应该配置成允许TCP数据流量通过你为对象选择的端口。

RemotingConfiguration.RegisterWellKnownServiceType(
typeof(ydglDB), 
  
"ydglDB", WellKnownObjectMode.SingleCall); 

这行代码设置了服务中的一些参数和把欲使用的对象名字与远程对象进行绑定,第一个参数是绑定的对象,第二个参数是TCP或HTTP信道中远程对象名字的字符串,第三个参数让容器知道,当有对对象的请求传来时,应该如何处理对象。尽管WellKnownObjectMode.Single对所有的调用者使用一个对象的实例,但它为每个客户生成这个对象的一个实例。

完整的对象代码如下所示:

using System;

using System.Drawing;

using System.Collections;

using System.ComponentModel;

using System.Windows.Forms;

using System.Data;

using System.Runtime.Remoting;

using System.Runtime.Remoting.Channels;

using System.Runtime.Remoting.Channels.Tcp;

using ydglServerClassLibrary1;

namespace ydglserver1

{

     
/// <summary>

     
/// Form1 的摘要说明。

     
/// </summary>


     
public class Form1 : System.Windows.Forms.Form

     
{

         
private System.Windows.Forms.PictureBox pictureBox1;

         
private System.Windows.Forms.Button button1;

         
private System.Windows.Forms.Button button2;

         
private System.Windows.Forms.Button button3;

         
private System.Windows.Forms.Label label1;

         
private System.Windows.Forms.Label label2;

         
private System.Windows.Forms.Label label3;

         
private System.Windows.Forms.ComboBox comboBox1;

         
/// <summary>

         
/// 必需的设计器变量。

         
/// </summary>


         
private System.ComponentModel.Container components = null;

 

         
public Form1()

         
{

              
//

              
// Windows 窗体设计器支持所必需的

              
//

              InitializeComponent();

 

              
//

              
// TODO: 在 InitializeComponent 调用后添加任何构造函数代码

              
//

         }


 

         
/// <summary>

         
/// 清理所有正在使用的资源。

         
/// </summary>


         
protected override void Dispose( bool disposing )

         
{

              
if( disposing )

              
{

                   
if (components != null

                   
{

                       components.Dispose();

                   }


              }


              
base.Dispose( disposing );

         }


 

         
Windows 窗体设计器生成的代码

 

         
/// <summary>

         
/// 应用程序的主入口点。

         
/// </summary>


         [STAThread]

         
static void Main() 

         
{

              Application.Run(
new Form1());

         }


 

         
private void Form1_Load(object sender, System.EventArgs e)

         
{

              
//注册信道

              

              TcpChannel chan
=new TcpChannel(8085);

              ChannelServices.RegisterChannel(chan);

              
//注册提供服务的远程对象

              RemotingConfiguration.RegisterWellKnownServiceType(
typeof(ydglDB),"ydglDB",WellKnownObjectMode.Singleton);

              

         }


     }


}


第三步:创建Remote客户端程序

ydgl是我们为对在上面创建的ydglServer远程对象进行测试而创建的。要创建这一工程,可以依次点击“文件”
->“创建”->“工程”,然后选择创建一个windows Application类型、名字为ydgl的工程名。象在第二步中那样,我们需要添加对在第一步中创建的DLL文件和System.Runtime.Remoting DLL的引用。 

下面的代码中有二行对于.NET remoting而言是特别重要的。第一行创建了一个TCP客户端信道,该信道并不是绑定在一个端口上的;第二行获取了一个对远程的ydgldb对象的引用。




using System;

using System.Drawing;

using System.Collections;

using System.ComponentModel;

using System.Windows.Forms;

using System.Data;

using System.Runtime.Remoting;

using System.Runtime.Remoting.Channels;

using System.Runtime.Remoting.Channels.Tcp;

using ydglServerClassLibrary1; 

 

namespace WinUI

{

     
/// <summary>

     
/// Form1 的摘要说明。

     
/// </summary>


     
public class Form1 : System.Windows.Forms.Form

     
{

         
private System.Windows.Forms.MainMenu mainMenu1;

         
private System.Windows.Forms.MenuItem menuItem1;

         
private System.Windows.Forms.MenuItem menuItem2;

         
private System.Windows.Forms.MenuItem menuItem3;

         
private System.Windows.Forms.MenuItem menuItem4;

         
private System.Windows.Forms.MenuItem menuItem5;

         
private System.Windows.Forms.MenuItem menuItem6;

         
private System.Windows.Forms.MenuItem menuItem7;

         
private System.Windows.Forms.MenuItem menuItem8;

         
private System.Windows.Forms.MenuItem menuItem9;

         
private System.Windows.Forms.MenuItem menuItem10;

         
private System.Windows.Forms.MenuItem menuItem11;

         
private System.Windows.Forms.ToolBar toolBar1;

         
private System.Windows.Forms.StatusBar statusBar1;

         
private System.Windows.Forms.ToolBarButton toolBarButton1;

         
private System.Windows.Forms.ToolBarButton toolBarButton2;

         
private System.Windows.Forms.ToolBarButton toolBarButton3;

         
private System.Windows.Forms.ToolBarButton toolBarButton4;

         
private System.Windows.Forms.ToolBarButton toolBarButton5;

         
private System.Windows.Forms.ImageList imageList1;

         
private System.Windows.Forms.DataGrid dataGrid1;

         
private System.Windows.Forms.Button button1;

         
private System.ComponentModel.IContainer components;

         
private DataSet ds1;

         
private System.Windows.Forms.Button button2;

         
private ydglDB ydglDB1;

 

         
public Form1()

         
{

              
//

              
// Windows 窗体设计器支持所必需的

              
//

              InitializeComponent();

 

              
//

              
// TODO: 在 InitializeComponent 调用后添加任何构造函数代码

              
//

         }


 

         
/// <summary>

         
/// 清理所有正在使用的资源。

         
/// </summary>


         
protected override void Dispose( bool disposing )

         
{

              
if( disposing )

              
{

                   
if (components != null

                   
{

                       components.Dispose();

                   }


              }


              
base.Dispose( disposing );

         }


 

         
Windows 窗体设计器生成的代码

 

         
/// <summary>

         
/// 应用程序的主入口点。

         
/// </summary>


         [STAThread]

         
static void Main() 

         
{

              RemotingConfiguration.RegisterWellKnownClientType(
typeof(ydglDB),"tcp://10.176.174.20:8085/ydglDB");

              

 

              Application.Run(
new Form1());

         }


 

         
private void menuItem3_Click(object sender, System.EventArgs e)

         
{

         

         }


 

         
private void Form1_Load(object sender, System.EventArgs e)

         
{

              

 

              ydglDB1
=new ydglDB();

              

         }


 

          
private void menuItem10_Click(object sender, System.EventArgs e)

         
{

         

         }


 

         
private void toolBar1_ButtonClick(object sender, System.Windows.Forms.ToolBarButtonClickEventArgs e)

         
{

         

         }


 

         
private void sqlConnection1_InfoMessage(object sender, System.Data.SqlClient.SqlInfoMessageEventArgs e)

         
{

         

         }


 

         
private void dataGrid1_Navigate(object sender, System.Windows.Forms.NavigateEventArgs ne)

         
{

         

         }


 

         
private void button1_Click(object sender, System.EventArgs e)

         
{

              

              ydglDB1.Update_bm_gdfgs(ds1);

             

         }


 

         
private void button2_Click(object sender, System.EventArgs e)

         
{

              ydglDB1.InitializeComponent();

              ds1
=ydglDB1.Get_bm_gdfgs();

              dataGrid1.DataSource
=ds1.Tables[0];

         }


 

         

     }


}
 

 

关于作者:本文作者范小多,是方向软件的软件工程师。他目前在中国成都方向软件技术有限公司工作,从事.net,Sybase的方面的开发和研究。
Email:fanxiaoduo@yahoo.com.cn
联系地址:成都市金牛区圃园南二路3号丽景湾8
-1-14 
邮编:
641001


 



作者Blog:http:
//blog.csdn.net/fanxiaoduo/
posted on 2005-03-17 12:40  dragonpro  阅读(728)  评论(1)    收藏  举报

Free Web Counter