技术开发 频道

使用基于接口的远程对象配置文件

【IT168技术文档】

  在开发.Net Remoting Components时,可以通过使用Remoting Configuration file来简化代码并提高配置的灵活性。

  但是,如果Client端没有Remote Objects的具体实现,只有引用interface,则Client端的configuration file就不行了(Server端应该不存在这种情况)。当然,你可以使用如下的代码得到Remote Object:

IHome objHome = (YourNameSpace.BusinessFacade.IHome) Activator.GetObject(typeof(YourNameSpace.BusinessFacade.IHome), "http://<ip address>/YourApplicationName/remotingObject.soap");
注:这里IHome假设是由Server和Client端共享的interface定义。
 
  这样将Remote URL编码在代码里面,显然就没有使用Configuration文件配置灵活了。针对上述问题,由如下几种解决办法:
 
1. 通过在Client的配置文件<appSettings>增加entry
 
如:<add key="Home.Location" value="http://<ip address>/ YourApplicationName/remotingObject.soap" />
 
  然后,通过ConfigurationSettings.AppSettings["Home.Location"];来获取Remote URL。
 
2. Ingos RemotingHelper class
 
  Ingo是《Advanced .Net Remoting》一书的作者,RemotingHelper class在Reference 1的URL可以查到。通过使用RemotingHelper class,你可以像使用正常的Remoting Configuration配置文件一样来配置Remote URL。
 
下面看看代码实现部分:
RemotingHelper class using System; using System.Collections; using System.Runtime.Remoting; //根据传入的type类型,从Hashtable中获取WellKnownClientTypeEntry //然后通过调用Activator.GetObject()方法,得到需要的Remote Object class RemotingHelper { private static bool _isInit; private static IDictionary _wellKnownTypes; public static Object GetObject(Type type) { if (! _isInit) InitTypeCache(); WellKnownClientTypeEntry entr = (WellKnownClientTypeEntry) _wellKnownTypes[type]; if (entr == null) { throw new RemotingException("Type not found!"); } return Activator.GetObject(entr.ObjectType,entr.ObjectUrl); } //负责初始化Hashtable, 并根据Remoting Configuration配置文件 //填入Remote Object Type和WellKnownClientTypeEntry。 public static void InitTypeCache() { _isInit = true; _wellKnownTypes= new Hashtable(); foreach (WellKnownClientTypeEntry entr in RemotingConfiguration.GetRegisteredWellKnownClientTypes()) { if (entr.ObjectType == null) { throw new RemotingException("A configured type could not " + "be found. Please check spelling"); } _wellKnownTypes.Add (entr.ObjectType,entr); } } }
3. 示例演示Demo
 
Client端配置文件
<configuration> <system.runtime.remoting> <application> <channels> <channel ref="http" /> </channels> <client> <wellknown type="IFooBar, MyInterfaces" url="http://localhost:5555/FooBar.soap" /> </client> </application> </system.runtime.remoting> </configuration>
  其中:IfooBar为接口,MyInterfaces.DLL为接口的assembly文件,这个配置文件与标准的Remoting Configuration配置文件一样。
//Client端调用上述RemotingHelp class using System; using System.Runtime.Remoting; class Client { static void Main(string[] args) { String filename = "client.exe.config"; RemotingConfiguration.Configure(filename); //这里不能使用new关键字来获取Remote Object //需要通过RemoteHelper.GetObject()方法来获取Remote Object. IFooBar obj = (IFooBar) RemotingHelper.GetObject(typeof(IFooBar)); Console.WriteLine("Done..."); } }
Summary & Improvement
 
  其实,上面Ingos RemotingHelper class存在一个问题,就是当有2个或多个Remote Objects实现相同的interface,如IFooBar,并且存在与同一个assembly文件内,在这种情况下RemotingHelper class就有问题了,因为Hashtable中不允许存在两个相同的key值。
 
  针对这样情况,有一个解决办法是:在Client端的配置文件只写一个<wellknown>:<wellknown type="IFooBar, MyInterfaces" url="http://localhost:5555/FooBar.soap" />
 
  通过RemotingHelper class获取Remote Object,该Remote Object的作用是获取真正所需要的其他Remote Objects并调用相应的方法。
 
  如该Remote Object命名为FooBarManager,实现IFoobBar接口,并且提供一个方法GetRequiredFooBar()。Client端通过调用FooBarManager.GetRequiredFooBar()来获取真正要求的FooBar对象,并调用相应的方法。

0
相关文章