技术开发 频道

如何使用基于接口的Remote Objects的配置文件


【IT168 技术文档】在开发
.Net Remoting Components时,可以通过使用Remoting Configuration file来简化代码并提高配置的灵活性,在article.Net Remoting配置文件的用法》中有比较详细的介绍。

 

   
  

但是,如果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假设是由ServerClient端共享的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. Ingo’s RemotingHelper class

 

Ingo是《Advanced .Net Remoting》一书的作者,RemotingHelper classReference 1URL可以查到。

 

通过使用RemotingHelper class,你可以像使用正常的Remoting Configuration配置文件一样来配置Remote URL

 

 

  下面看看代码实现部分:

(1) 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 TypeWellKnownClientTypeEntry

 

  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

 

1Client端配置文件

<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配置文件一样。

 

 

2Client端调用上述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...");

 

  } 

 

}

 

 

  4. Summary & Improvement
 
其实,上面Ingo’s 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
相关文章