为了不在客户端放置通用库文件,先定义接口,让通用库继承接口,然后在客户端只使用接口.问题是:在客户端使用通用库时 
ClientActivatedType CAObject = new ClientActivatedType();
ILease serverLease = (ILease)RemotingServices.GetLifetimeService(CAObject);
MyClientSponsor sponsor = new MyClientSponsor();
serverLease.Register(sponsor);
是可以通过的,客户端发起租约成功.但,当只引用接口时:
IcskGeneral CAObject ;
CAObject=(IcskGeneral)Activiter.GetObject(TypeOf(IcskGeneral),url);
ILease serverLease = (ILease)RemotingServices.GetLifetimeService(CAObject);
报错:错误 1 与“System.Runtime.Remoting.RemotingServices.GetLifetimeService(System.MarshalByRefObject)”最匹配的重载方法具有一些无效参数 
错误2 参数“1”: 无法从“cdling.IcskGeneral”转换为 system.MarshalByRefObject”报错时光标在GetLifetimeService(CAObject)的CAObject 上.在任炅的讲座中只提到过,但在示例中都是引用的通用库,请问大师门如何解决,因为我不想把通用库放到客户端去!

解决方案 »

  1.   

    试一试:IcskGeneral CAObject ;
    CAObject=(IcskGeneral)Activiter.GetObject(TypeOf(IcskGeneral),url);//强行转换一下
    System.MarshalByRefObject tmp = (System.MarshalByRefObject)CAObject;ILease serverLease = (ILease)RemotingServices.GetLifetimeService(tmp);
      

  2.   

    补充:在使用Activiter.GetObject()时注释了config 中的 <client Activited....../client>
    捕获的错误:uri is null.
      

  3.   

    LZ,这事儿还就是这么简单,如果你不做System.MarshalByRefObject的强行转换,编译都过不去,除非你的IcskGeneral根本就不是接口,而是继承了System.MarshalByRefObject的一个类. 另外你到底试了没有?如果CAObject=(IcskGeneral)Activiter.GetObject(TypeOf(IcskGeneral),url)真得到了远程的MarshalByRefObject,象我上边说的那样做应该可以得到它的ILease.
      

  4.   

    RemotingServices.GetLifetimeService(CAObject);把GetLifetimeService的参数改成IcskGeneral接口要搞清楚继承关系ClientActivatedType 能够转化为IcskGeneral
    但是IcskGeneral接口不能转换为ClientActivatedType
      

  5.   

    改为任炅的示例一样,将接口放在cskGeneral 中,为什么配置文件能运行,而使用代码则失败,请指点:
    server configuration
    <configuration>
    <system.runtime.remoting>
    <application >
    <service>
    <activated type="cdling.ClientActivatedType, cskGeneral" objectUri="cskGeneral.rem"/>
    </service>
    <channels>
    <channel port="8001" ref="tcp">
    <serverProviders>
    <formatter ref="soap" typeFilterLevel="Full"/>
    <formatter ref="binary" typeFilterLevel="Full"/>
    </serverProviders>
    </channel>
    </channels>
    </application>
    </system.runtime.remoting>
    </configuration>client configuration
    <configuration>
    <system.runtime.remoting>
    <application>
    <client url="tcp://localhost:8001">
    <activated type="cdling.ClientActivatedType, cskGeneral"/>
    </client>
    <channels>
    <channel ref="tcp" port="0">
    <serverProviders>
    <formatter ref="soap" typeFilterLevel="Full"/>
    <formatter ref="binary" typeFilterLevel="Full"/>
    </serverProviders>
    </channel>
    </channels>
    </application>
    </system.runtime.remoting>
    </configuration>
    而在客户端不作用配置文件就出错了:
                // 通过编程设置反序列的级别
                BinaryServerFormatterSinkProvider provider = new BinaryServerFormatterSinkProvider();
                provider.TypeFilterLevel = TypeFilterLevel.Full;
                // 设置通道属性
                IDictionary props = new Hashtable();
                props["port"] = 0;
                //注册TCP通道,用于连接自己或者他人的服务器。
                TcpChannel chn = new TcpChannel(props, null, provider);
                ChannelServices.RegisterChannel(chn, false);
                IcskGeneral CAObject = (IcskGeneral)Activator.GetObject(typeof(cdling.IcskGeneral), "tcp://localhost:8001/cskGeneral.rem");
                Console.WriteLine("Client-activated object: " + CAObject.test("客户端发出的数据!"));运行至此报错:找不到请求的服务.
      

  6.   

    配置文件比代码多一种Format Provider: <formatter ref="soap" typeFilterLevel="Full"/>. 也许和这个有关系,在程序代码中也加上这个试试. 或者用一个简单的办法,把服务器方的<formatter ref="soap" typeFilterLevel="Full"/>去掉,只用一中BinaryS标Format Provider.
      

  7.   

    在服务器端再加上一个:
    ClientActivatedType obj = new ClientActivatedType();
    ObjRef objref = RemotingServices.Marshal(obj,"ClientActivatedType.rem")
    可以解决:找不到请求的服务.的问题,而讲座中没有这样做哇,是为什么呢?
      

  8.   

    ClientActivatedType   CAObject   =   new   ClientActivatedType(); 
    这里错了.
    若要在客户端使用接口,就必须是服务端激活模式.否则客户端怎么知道构造函数的签名呢?!
      

  9.   

    //强行转换一下 
    System.MarshalByRefObject   tmp   =   (System.MarshalByRefObject)CAObject; 
    上面的方式是可以的,我的就是这样用的。
    虽然客户端对象表现为接口类型,但从服务端返回的实际对象是继承于System.MarshalByRefObject的。但我也有一个问题
    我注册续约者在局域网内可以,但到Internet上就不行了。
    服务端方法返回对象与数据包都是可以的,就是传递对象(作为方法参数)到服务端去,就不行了。
    有没高手知道原因?