Factory Pattern在.Net Remoting Architecture中的实现 | |||
混合法混合法需要使用 RecordingsFactory SAO,它提供了创建 RecordingsManager CAO 的方法。(如果您不熟悉 SAO 示例,请参阅"使用服务器激活对象通过 .NET Remoting 实现 Broker"。)下面的类图表描述了总体解决方案。 图 1:混合法的结构 这种实现使用了 SAO 示例中所描述的共享接口法。IRecordingsManager和 IRecordingsFactory 这两个接口位于客户端和服务器所共享的程序集中。IRecordingsFactory 有一个 Create 方法,它可以返回一个对象来实现 IRecordingsManager 接口。这是 AbstractFactory [Gamma95] 模式的一个例子。因为客户端只依靠接口,所以无需传送服务器代码。当客户端需要 IRecordingsManager 对象时,它调用 IRecordingsFactory 实例的 Create 方法。这样,客户端就可以控制 IRecordingsManager 对象的生存期,而无需实现该对象。共享程序集中的两个接口是: IRecordingsManager.cs 以下示例显示了 IRecordingsManager 接口: using System; using System.Data; public interface IRecordingsManager { DataSet GetRecordings(); } IRecordingsFactory.cs 以下示例显示了 IRecordingsFactory 接口: using System; public interface IRecordingsFactory { IRecordingsManager Create(); } 这些对象的服务器实现(RecordingsFactory 和 RecordingsManager)非常简单,并且包含在它们自己的、名为 Server 的程序集中。 RecordingsFactory.cs 该类扩展了 MarshalByRefObject,并实现了 IRecordingsFactory 接口: using System; public class RecordingsFactory : MarshalByRefObject, IRecordingsFactory { public IRecordingsManager Create() { return new RecordingsManager(); } } RecordingsFactory 对象是服务器激活对象。该实现只是对 RecordingsManager 类型调用 new。该 RecordingsManager 对象是在服务器上创建的,并且,不是作为 RecordingsManager 对象、而是作为 IRecordingsManager 接口返回的。利用这种机制,客户端就可以依赖于接口而不是实现。 RecordingsManager.cs RecordingsManager 类所需要的唯一更改是,它现在实现的是 IRecordingsManager 接口。 using System; using System.Reflection; using System.Data; using System.Data.SqlClient; public class RecordingsManager : MarshalByRefObject, IRecordingsManager { public DataSet GetRecordings() { Console.WriteLine("Assembly: {0} - filling a request", Assembly.GetEntryAssembly().GetName().Name); String selectCmd = "select * from Recording"; SqlConnection myConnection = new SqlConnection( "server=(local);database=recordings;Trusted_Connection=yes"); SqlDataAdapter myCommand = new SqlDataAdapter(selectCmd, myConnection); DataSet ds = new DataSet(); myCommand.Fill(ds, "Recording"); return ds; } } HttpServer.cs 混合法中的服务器初始化代码用于为服务器激活的 RecordingsFactory 对象配置远程处理框架。激活方式与所使用的通道和协议无关,因此与以前一样(端口 8100 上的 HTTP 协议)。 using System; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Http; public class HttpServer { static void Main(string[] args) { HttpChannel channel = new HttpChannel(8100); ChannelServices.RegisterChannel(channel); RemotingConfiguration.RegisterWellKnownServiceType( typeof(RecordingsFactory), "RecordingsFactory.soap", WellKnownObjectMode.Singleton); Console.ReadLine(); } } 在该代码中,RecordingsFactory 类型与 URL http://localhost:8100/RecordingsFactory.soap 相关联。 HttpClient.cs 客户端代码显示了这种方式的混合性质。首先使用 Activator.GetObject 方法从服务器检索 IRecordingsFactory 对象。然后,使用这个服务器激活对象来调用 Create 方法,以便实例化一个 IRecordingsManager 对象。这个新实例化的对象是在服务器上创建的,但它是一个远程对象。 using System; using System.Data; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Http; public class HttpClient { [STAThread] static void Main(string[] args) { HttpChannel channel = new HttpChannel(); ChannelServices.RegisterChannel(channel); IRecordingsFactory factory = (IRecordingsFactory) Activator.GetObject(typeof(IRecordingsFactory), "http://localhost:8100/RecordingsFactory.soap"); Console.WriteLine("Client.main(): Factory acquired"); IRecordingsManager mgr = factory.Create(); DataSet ds = mgr.GetRecordings(); Console.WriteLine("Recordings Count: {0}", ds.Tables["recording"].Rows.Count); } } | |||
| |||
| |||
|
远程对象的激活方式 | |||
2、远程对象的激活方式
(1) 服务器端激活,又叫做WellKnow方式,很多又翻译为知名对象。为什么称为知名对象激活模式呢?是因为服务器应用程序在激活对象实例之前会在一个众所周知的统一资源标识符(URI)上来发布这个类型。然后该服务器进程会为此类型配置一个WellKnown对象,并根据指定的端口或地址来发布对象。.Net Remoting把服务器端激活又分为SingleTon模式和SingleCall模式两种。
(1) SingleTon模式
RemotingConfiguration.RegisterWellKnownServiceType( (2)SingleCall模式
RemotingConfiguration.RegisterWellKnownServiceType( (3)客户端激活模式
RemotingConfiguration.ApplicationName = "ServiceMessage"; 为什么要在注册对象方法前设置ApplicationName属性呢?其实这个属性就是该对象的URI。对于WellKnown模式,URI是放在RegisterWellKnownServiceType()方法的参数中,当然也可以拿出来专门对ApplicationName属性赋值。而RegisterActivatedServiceType()方法的重载中,没有ApplicationName的参数,所以必须分开。 2、客户端获得远程对象。 与服务器端相同,不同的激活模式决定了客户端的实现方式也将不同。不过这个区别仅仅是WellKnown激活模式和客户端激活模式之间的区别,而对于SingleTon和SingleCall模式,客户端的实现完全相同。
要获得服务器端的知名远程对象,可通过Activator进程的GetObject()方法来获得: ServerRemoteObject.ServerObject serverObj = (ServerRemoteObject.ServerObject)Activator.GetObject( 首先以WellKnown模式激活,客户端获得对象的方法是使用GetObject()。其中参数第一个是远程对象的类型。第二个参数就是服务器端的uri。如果是http通道,自然是用http://localhost:8080/ServiceMessage了。因为我是用本地机,所以这里是localhost,你可以用具体的服务器IP地址来代替它。端口必须和服务器端的端口一致。后面则是服务器定义的远程对象服务名,即ApplicationName属性的内容。 (2) 客户端激活模式
RemotingConfiguration.RegisterActivatedClientType( 2) 调用进程Activator的CreateInstance()方法。这个方法将创建方法参数指定类型的类对象。它与前面的GetObject()不同的是,它要在客户端调用构造函数,而GetObject()只是获得对象,而创建实例是在服务器端完成的。CreateInstance()方法有很多个重载,我着重说一下其中常用的两个。 这里的参数args是一个object[]数组类型。它可以传递要创建对象的构造函数中的参数。从这里其实可以得到一个结论:WellKnown激活模式所传递的远程对象类,只能使用默认的构造函数;而Activated模式则可以用户自定义构造函数。activationAttributes参数在这个方法中通常用来传递服务器的url。 假设我们的远程对象类ServerObject有个构造函数: ServerObject(string pName,string pSex,int pAge) 那么实现的代码是: object[] attrs = {new UrlAttribute("tcp://localhost:8080/ServiceMessage")};
参数说明一目了然。注意这个方法返回值为ObjectHandle类型,因此代码与前不同: object[] attrs = {new UrlAttribute("tcp://localhost:8080/EchoMessage")}; 这个方法实际上是调用的默认构造函数。ObjectHandle.Unwrap()方法是返回被包装的对象。
| |||
| |||
| |||
|
2005-7-26 | |||
NET Web services vs. remoting: Which one will work best for your app? | |||
Microsoft has made a tremendous amount of noise about building applications with Web services, and its .NET Framework simplifies the task of working with them. But while Web services represent a great way to build applications, they are ideally suited for clients outside the firewall calling components on your server over the Internet.
If both your clients and components are inside the firewall, Web services may work fine; however, all of your data travels through a Web server, which can slow performance. To speed things up, Microsoft provides a binary mechanism called remoting. Let's take a look at how remoting works, and I'll share some code examples that show you how to set it up in a sample Web service. How Web services work with .NET For a brief explanation on how Web services work, and specifically how they work in .NET, check out this sidebar. .NET remoting While Web services are arguably the best way for clients outside of your organization to access components, what about components within your organization? Many companies are building Web services and using them internally. There is nothing wrong with this approach, but it doesn't provide the best performance. If components are created in .NET and the client applications are .NET, you can place components on shared servers and access them via remoting. Remoting is the .NET technology that replaces DCOM allowing you to communicate between a client application and components in a binary format. As a result, remotable components are faster than Web services. However, creating remotable components is more difficult because you must add additional code to your components. This code isn't much more complicated than its Web service counterpart, but you cannot directly instantiate a remote component. Instead, you must create a host application that instantiates the component and listens for requests. The good news is that this host can be a Windows service, a Windows application, a console application, or anything that can run and hold the object open. Not only do you have to create a host application, you must also make several decisions about the remotable object, such as which channel to use. .NET supports both HTTP and TCP channels. The HTTP channel actually uses the SOAP protocol to transport messages to and from remotable objects; this means all messages are serialized to XML. The TCP channel uses a binary stream to transport the messages. Next, you must choose between two activation modes: Singleton and SingleCall. Singleton types have only one instance of an object at any time. All client requests are serviced by that single instance. This allows you to "share" data between requests or, more likely, maintain state between requests. SingleCall types, on the other hand, create a new instance of the object for each client request. SingleCall objects are more like Web services because they are stateless and are created and destroyed for each request. .NET is architected in such a way that remotable components can change channels without being recompiled. You can place the channel information in a configuration file and change from TCP to HTTP or vice versa without recompiling the application. Similarly, you can change a configuration file for the client to match the channel that the host is using. Quick code comparisons To see some quick examples of a Web service and a remotable object with host, I'll use the example I used in a previous article in which I created a simple Web service. The entire code for the Web service follows: <%@ WebService Language="VB" Class="ConvertMoney" %> Imports System.Web.Services <WebService()>Public Class ConvertMoney Inherits WebService <WebMethod()>Public Function _ PoundsToDollars(BritishPounds As Double) As Double Return BritishPounds * 1.44 End Function End Class Here is the code to implement the same thing with a remotable component: Public Class ConvertMoney Inherits System.MarshalByRefObject Public Function _ PoundsToDollars(ByVal BritishPounds As Double) As Double Return BritishPounds * 1.44 End Function End Class The component looks simpler. In fact, the only difference is that it inherits from System.MarshalByRefObject. But remember, you need to build a host application that instantiates the object and listens for requests. The code for the host object could look like this: Imports System.Runtime.Remoting Imports System.Runtime.Remoting.Channels Imports System.Runtime.Remoting.Channels.Tcp Imports RemoteConvertMoney Module Module1 Sub Main() Dim tcpChannel As New TcpChannel(7777) ChannelServices.RegisterChannel(tcpChannel) Dim ChangeMoney As New ConvertMoney RemotingServices.Marshal(ChangeMoney, "ConvertMoney") Console.ReadLine() End Sub End Module In this case, the host application is a console application. You start the application and it launches a console application and creates the object. The console application runs until someone presses the [Enter] key, and the object is available until needed. As you can see, the amount of work required to create the remotable component is more than the Web service. Make the choice There is no absolute answer to whether you should choose Web services or remoting in most cases. If your entire distributed application is inside your organization firewall and performance is critical, remoting via the TCP channel is the best choice. If the entire application is inside the firewall and performance isn't as critical, or if you want to keep things as simple as possible, Web services is a better choice. But, if you need to allow access to clients other than .NET, you'll need to use Web services regardless of whether or not the client is inside or outside the firewall. In the end, the choice is left to the developer, so you'll need thorough knowledge of both technologies to make a proper decision. | |||
| |||
| |||
|
Web services in .NET | |||
Web services, called XML Web services by Microsoft, are the components that are instantiated via HTTP. Data is passed to, and received from, Web services using HTTP and SOAP, which is clear text and based upon XML. Thanks to Web services, passing data between different operating systems on different platforms has been simplified.
Web services use HTTP to communicate, and this requires a Web server. Requests must be turned into SOAP messages that are sent to the Web server. There, they are processed, the object is instantiated, the method is executed, and the data is placed in an XML format to be returned to the client. The client application processes the XML as necessary. Given this scenario, it is no great surprise that Web services are slow when compared to direct binary access of objects. Without Web services, data does not have to be serialized to XML and deserialized on the client. Requests and returns do not have to flow through a Web server. Of course, Web services do offer advantages. First, they can be called by almost any client. The client does not have to be a .NET application. In fact, the client machine does not need to be running a Windows operating system. Second, because Web services use SOAP, the data flows across firewalls easily; all data is passed as XML. Finally, as far as .NET is concerned, the .NET Framework makes it incredibly easy to create Web services, and you can do so with just a few lines of code. | |||
| |||
| |||
|
2005-7-25 | |||
Building Distributed Apps? Use XML Web Services, Not Remoting (Mostly) | |||
If you have been wondering whether to use XML Web services or .NET Remoting, here's a simple answer: Use XML Web services most of the time. XML Web services are the same as marshal-by-value .NET Remoting, but using them is much easier than using Remoting from scratch. Marshal-by-value remoting (XML Web services) means that you get XML-serialized data from your remote server. Sometimes, you may need dynamic event behavior or you may not want to move massive amounts of data and need a little more control. In this instance, you peel back the XML Web services layer and start building directly on top of .NET Remoting with marshal-by-reference objects and event sinks. Mostly not, though. This article looks at the basic technologies that support XML Web services and provides a brief demonstration of how to produce and consume Web services. XML Web Services Will DoXML Web services in .NET are built on top of .NET Remoting. For all intents and purposes, a Web service is marshal-by-value .NET Remoting. The rumor mill also suggests that .NET Remoting may be completely concealed by XML Web services in the future, making advanced features of Remoting like event sinks available using Web services. I hope you are more comfortable with XML Web services. Now, when you have to choose between Remoting and Web services, you are prepared to make a decision. Most of the time when you create distributed applications, XML Web services will do. | |||
| |||
| |||
|
XML Web services .NET Remoting and System.NET Communication Guidelines | |||
1. An XML Web Service call is essentially a SOAP message sent over the Http Protocol 2. .NET Remoting is a communication infrastructure that provides access to remote objects over the TCP protocol, Http protocol or some other custom protocol 3. XML Web Services uses SOAP (Simple Object Access Protocol) which is an XML message to communicate over the widely used Http protocol. 4. .NET Remoting provides object services over the Http or TCP protocol. .NET Remoting could be a SOAP message over a Http protocol (similar to XML Web service) or a TCP protocol or a Binary Formatted message over the TCP Protocol or Http Protocol. 5. When objects are remoted over a TCP Protocol using Binary Formatting or Encoding you have the best performance over any .NET Remoting Service or XML Web service. 6. If you intend to send SOAP messages over the Http protocol, do not use .NET Remoting, use XML Web services. The medium is the same in both instances and XML Web services deliver more speed than .NET Remoting service using SOAP Formatting over a Http protocol. 7. Using IIS as a Host or server offers scalability to both Remoted objects and XML Web Services. XML Web Services use IIS (Internet Information Server) as a Host and .NET Remoting can use IIS, Windows Services, Windows Form, Console Application as a Host or Server. 8. You can build your own interprocess communication solution using classes from the System.NET namesapce. 9. Using IIS as a host for XML Web services or .NET Remoting service offers security features like authentication and also state management. 10. Binary Formatting over the TCP protocol requires additional ports other that port 80 (which IIS uses) to be opened on your web server. These additional ports could pose security considerations. 11. Using .NET Remoting offers some flexibility for the activation of objects (they can be activated on the server or client), object life time management using leases and object instantiation management (SingleCall or Singleton modes.) 12. .NET Remoting offers access to a richer object oriented programming model than .XML Web services. 13. XML Web services offers a richer set of options for formatting SOAP messages than SOAP Formatting in a .NET Remoting Context. 14. XML Web services uses SOAP to communicate between two computers and is better suited for exchanging messages with applications not built with .NET while .NET Remoting is optimized for exchanging messages between .NET clients. | |||
| |||
| |||
|
设计 .NET 应用程序 |
升级到 Microsoft .NET Paul D. Sheriff 出处:Microsoft 摘要:本文概要介绍 .NET 应用程序中的各种典型物理结构之间的区别,这些结构已被证明是很有用的。针对每种结构介绍了其适用方案、实现方式和优缺点。本文同时介绍了两层、三层和 N 层应用程序。 注意:
目标
前提条件
目录 两层应用程序结构 两层应用程序结构典型的两层应用程序是使用 ADO.NET 直接与数据库服务器(如 Microsoft SQL Server?)进行通信的客户端应用程序(参见图 1)。除 ADO.NET 外,在客户端应用程序和数据库之间没有任何其他层。有关 ADO.NET 的详细信息,请参阅 .NET 框架文档、本系列的其他文章或使用 MSDN 搜索引擎。 图 1:两层应用程序包括客户端应用程序和数据存储(如 Microsoft SQL Server) 何时使用两层结构两层应用程序适用于没有或只有少量窗体的小型应用程序。对于使用本文中介绍的其他 N 层技术的应用程序,其原型也可算是两层应用程序。但是,两层应用程序不太适用于企业环境,因为开发和维护的时间及成本不好控制。 典型的实现方式开发两层应用程序时可以采用多种技术。所有技术均使用 ADO.NET、一个客户端界面(如桌面或基于 Web 的应用程序)和一个数据库(如 SQL Server)。要使用两层应用程序结构,可以采用以下方式:
优点两层应用程序具有以下优点:
缺点两层应用程序开发方法具有以下缺点:
使用 XML Web Service 的三层应用程序另一种设计方式是使用 XML Web service,将数据库的访问单独分给另一个组件,该组件将把数据返回到前端应用程序。图 2 显示了这种设计方式。 有关使用 XML Web services 开发三层应用程序的详细信息,请使用 MSDN 搜索引擎。
何时使用此技术使用 XML Web service 的三层应用程序适用于基于 Web 的应用程序或 Microsoft Windows? 应用程序。如果需要桌面应用程序的丰富功能,而用户连接自多个不同的位置,并通过 HTTP 界面访问数据,则很适合使用此技术。 典型的实现方式要创建三层/XML Web service 应用程序,通常采用以下开发技术:
优点使用 XML Web service 的三层应用程序具有以下优点:
缺点此设计的缺点与典型的两层应用程序的缺点基本相同,因为它并没有分离业务规则,而只是分离了数据层。此外,表中的列名称也没有被提取到类中(将在下一节中介绍)。
使用 .NET Remoting 的三层应用程序这种类型的应用程序结构与使用 XML Web service 的三层应用程序几乎完全相同。唯一的区别是使用 .NET Remoting 代替 XML Web service 来包装数据访问层。图 3 显示了这种设计方式。 有关 .NET Remoting 的详细信息,请参阅本系列的其他文章或使用 MSDN 搜索引擎。
图 3:在 LAN 环境中,可以使用 .NET Remoting 来包装数据访问层 何时使用三层 .NET Remoting 技术使用 .NET Remoting 的三层应用程序适用于必须在 LAN 中的计算机之间分布的应用程序。这可能是出于业务原因,或者考虑到所涉及的工作成本,采用网络呼叫比较合理。 典型的实现方式要创建这种应用程序,通常采用以下开发技术:
优点使用 .NET Remoting 的三层应用程序与使用 XML Web service 的三层应用程序具有相同的基本优点。
缺点这种三层设计的缺点与使用 XML Web service 的三层设计的缺点相同。
逻辑 N 层应用程序使用 .NET 创建应用程序的最好方法是将所有逻辑进程分为不同的类。在典型的业务应用程序中,这通常包含业务规则组件、数据层组件和使用这些组件的前端代码。图 4 显示了这一方法。 有关设计 N 层应用程序的详细信息,请参阅本系列的其他文章或使用 MSDN 搜索引擎。
何时使用 N 层结构逻辑 N 层开发策略适用于所有类型的应用程序。无论是小型、中型、大型应用程序,还是桌面或 Web 应用程序,效果都很好。 典型的实现方式要创建这种应用程序,通常采用以下开发技术:
优点逻辑 N 层应用程序具有以下优点:
缺点逻辑 N 层应用程序只有两个较大的缺点:
使用 XML Web Service 的 N 层应用程序图 5 显示了如何进行逻辑 N 层应用程序设计并将其分布于多台计算机的示例。在此图中,可以看到使用了 XML Web service 来访问数据层。类型化数据集通过 HTTP 层返回到业务规则层。然后,客户端应用程序可以将该数据集用于用户界面的数据显示。
何时使用此技术如果需要桌面应用程序的丰富功能,而用户可能连接自很多远程位置,并且需要通过 HTTP 界面来获取数据,那么就可以采用这种 N 层 XML Web service 应用程序设计。将业务规则保留在客户端上有利于网络畅通,但如果这些规则更改频繁,则会增加一些维护更新工作。由于 .NET 可以复制新的 DLL 而无需注册,所以这些问题已经不象在以前的技术中那样严重。 这种方案也适用于基于 Web 的应用程序,其中由一台 Web 服务器提供数据,而由另一台 Web 服务器上的 Web 应用程序显示此数据。 典型的实现方式要创建这种应用程序,通常采用以下开发技术:这些技术与逻辑 N 层应用程序中的技术相同。
优点使用 XML Web service 的 N 层应用程序具有多个优点,其中很多与逻辑 N 层应用程序相同。
缺点使用 XML Web service 的 N 层应用程序开发方法也有一些缺点。其中大部分与使用逻辑 N 层应用程序开发方案的缺点相同。
其他 N 层应用程序技术当然,可以采用很多不同的技术来创建 N 层应用程序。例如,可以使用 .NET Remoting 在客户端层和业务规则层之间进行通信,如图 6 所示。
使用 N 层技术开发应用程序后,还可以采用多种方法对其进行配置。可以组合使用 .NET 中的任何可用方法来分离应用程序的各层。 迁移 Visual Basic 6.0 的 N 层应用程序程序员在以前版本的 Microsoft Visual Basic? 中使用 N 层技术已经有很多年了。如果有现成的 COM 组件,则可以很容易地为这些组件上加上 .NET 包装。之后,便可以获得如图 7 所示的结构。 有关在 .NET 中使用 COM 组件的详细信息,请参阅本系列的其他文章或使用 MSDN Web 站点 中的搜索引擎。
图 7:使用 .NET 可以方便地建立原有 COM 组件的接口 何时使用 Visual Basic 迁移技术如果具有大量的 COM 组件代码,并且这些组件已经包含了您的业务规则和数据访问例程,则适合使用这种技术。因为可以利用很多现有代码,从而降低进入 .NET 框架的成本。 典型的实现方式要创建这种应用程序,通常采用以下开发技术:
优点在 COM 接口外加上 .NET 包装,可以在使用现有代码的同时充分利用 .NET 的新功能,从而缩短开发周期。 缺点在 .NET 中使用 COM 包装具有以下缺点:
小结在开发 .NET 应用程序时,可以采用的结构形式几乎是无限的。易于创建和维护的结构才是最好的。当然,还要考虑其他设计目标,包括可缩放性、可靠性和可管理性等。在 MSDN 中,您可以找到许多相关主题的白皮书。 |
|
|
2005-7-19 |
ADO.NET创建关联的范例 |
SqlConnection custConn = new SqlConnection("Data Source=localhost;Integrated Security=SSPI;Initial Catalog=northwind;"); OleDbConnection orderConn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;" + custConn.Open(); DataSet custDS = new DataSet(); custDA.Fill(custDS, "Customers"); custConn.Close(); DataRelation custOrderRel = custDS.Relations.Add("CustOrders", foreach (DataRow pRow in custDS.Tables["Customers"].Rows) |