你真的了解Ioc与AOP吗?(4)
本系列的全部源代码及二进制文件可以从这里下载:IocInCSharp.rar
本部分示例代码请参考"src\Step4"目录
五、使用Remoting对原有系统进行改造
如果使用Remoting技术对HelloGenerator进行改造,使其具有分布式远程访问能力,那么在不使用Ioc技术的情况下,我们将会作出如下调整:
(1)让HelloGenerator继承自MarshalByRefObject类
如果要让某个对象具有分布式的功能,必须使其继承自MarshalByRefObject,这样才可以具有远程访问的能力。因此我们需要调整EnHelloGenerator和CnHelloGenerator的代码。这里以EnHelloGenerator为例:
+展开
-C#
using System;
namespace IocInCSharp
{
public class EnHelloGenerator : MarshalByRefObject, IHelloGenerator
{
public string GetHelloString(string name)
{
return String.Format("Hello, {0}", name);
}
}
}
namespace IocInCSharp
{
public class EnHelloGenerator : MarshalByRefObject, IHelloGenerator
{
public string GetHelloString(string name)
{
return String.Format("Hello, {0}", name);
}
}
}
(2)将修改后的HelloGenerator发布出去
在这一步中,我们创建了一个新的Console应用程序RemotingServer,并在其中注册了一个Channel,发布服务并进行监听。代码如下:
+展开
-C#
using System;
using System.Configuration;
using System.Collections;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using System.Runtime.Serialization.Formatters;
namespace IocInCSharp
{
public class Server
{
public static void Main()
{
int port = Convert.ToInt32(ConfigurationSettings.AppSettings["LocalServerPort"]);
try
{
BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider();
serverProvider.TypeFilterLevel = TypeFilterLevel.Full;
IDictionary props = new Hashtable();
props["port"] = port;
props["timeout"] = 2000;
HttpChannel channel = new HttpChannel(props, clientProvider, serverProvider);
ChannelServices.RegisterChannel(channel);
RemotingConfiguration.RegisterWellKnownServiceType(
typeof(EnHelloGenerator),
"HelloGenerator.soap",
WellKnownObjectMode.Singleton);
Console.WriteLine("Server started!\r\nPress ENTER key to stop the server...");
Console.ReadLine();
}
catch
{
Console.WriteLine("Server Start Error!");
}
}
}
}
using System.Configuration;
using System.Collections;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using System.Runtime.Serialization.Formatters;
namespace IocInCSharp
{
public class Server
{
public static void Main()
{
int port = Convert.ToInt32(ConfigurationSettings.AppSettings["LocalServerPort"]);
try
{
BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider();
serverProvider.TypeFilterLevel = TypeFilterLevel.Full;
IDictionary props = new Hashtable();
props["port"] = port;
props["timeout"] = 2000;
HttpChannel channel = new HttpChannel(props, clientProvider, serverProvider);
ChannelServices.RegisterChannel(channel);
RemotingConfiguration.RegisterWellKnownServiceType(
typeof(EnHelloGenerator),
"HelloGenerator.soap",
WellKnownObjectMode.Singleton);
Console.WriteLine("Server started!\r\nPress ENTER key to stop the server...");
Console.ReadLine();
}
catch
{
Console.WriteLine("Server Start Error!");
}
}
}
}
(3)全新的客户端调用代码
为了使得客户端MainApp能够调用到远程的对象,我们需要修改它的代码,注册相应的Channel并进行远程访问。修改后的MainApp代码如下:
+展开
-C#
using System;
using System.Configuration;
using System.Collections;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using System.Runtime.Serialization.Formatters;
namespace IocInCSharp
{
public class MainApp
{
public static void Main()
{
//建立连接
BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider();
serverProvider.TypeFilterLevel = TypeFilterLevel.Full;
IDictionary props = new Hashtable();
props["port"] = System.Convert.ToInt32(ConfigurationSettings.AppSettings["ClientPort"]);
HttpChannel channel = new HttpChannel(props, clientProvider, serverProvider);
ChannelServices.RegisterChannel(channel );
//创建远程对象
ISayHello sayHello = new SayHello();
string RemoteServerUrl = ConfigurationSettings.AppSettings["RemoteServerUrl"];
sayHello.HelloGenerator = (IHelloGenerator)Activator.GetObject(typeof(IHelloGenerator), RemoteServerUrl);
sayHello.SayHelloTo("zhenyulu");
}
}
}
using System.Configuration;
using System.Collections;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using System.Runtime.Serialization.Formatters;
namespace IocInCSharp
{
public class MainApp
{
public static void Main()
{
//建立连接
BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider();
serverProvider.TypeFilterLevel = TypeFilterLevel.Full;
IDictionary props = new Hashtable();
props["port"] = System.Convert.ToInt32(ConfigurationSettings.AppSettings["ClientPort"]);
HttpChannel channel = new HttpChannel(props, clientProvider, serverProvider);
ChannelServices.RegisterChannel(channel );
//创建远程对象
ISayHello sayHello = new SayHello();
string RemoteServerUrl = ConfigurationSettings.AppSettings["RemoteServerUrl"];
sayHello.HelloGenerator = (IHelloGenerator)Activator.GetObject(typeof(IHelloGenerator), RemoteServerUrl);
sayHello.SayHelloTo("zhenyulu");
}
}
}
在这段代码中,远程对象的创建是通过(IHelloGenerator)Activator.GetObject(typeof(IHelloGenerator), RemoteServerUrl)实现的。到此为止,我们就完成了对原有系统的Remoting改造。
经过调整后的系统,其组件间相互依赖关系如下图所示:
注意ICommon.dll文件在Client和Server端都有。
在整个调整过程中,我们修改了Server端的EnHelloGenerator以及CnHelloGenerator的代码,Client端的MainApp也 作了修改,以加入了远程访问机制。那么能不能对原有代码不作任何修改就实现远程访问机制呢?当然可以!不过我们还要请出Sping.net帮助我们实现这一切。
加支付宝好友偷能量挖...