按照<图4-7 两种类工厂方案的对比>想象的实现方式, 测试未通过。
将类工厂从MarshalByRefObject继承,将GetFactory()的静态声明去掉,将类工厂部署在服务器端;
在客户端使用单例保存类工厂的代理对象,使用此代理对象时发生错误。
Business.cs
using
System;
namespace Business
{
// bizFactory
public class bizFactory : MarshalByRefObject
{
public Biz getbiz1()
{
return new Biz1();
}
public Biz getbiz2()
{
return new Biz2();
}
public Biz getbiz3()
{
return new Biz3();
}
}
// abstruct class Biz
public abstract class Biz : MarshalByRefObject
{
public Biz()
{
Console.WriteLine("biz construct.");
}
~Biz()
{
Console.WriteLine("biz destory.");
}
public abstract string hi();
}
public class Biz1 : Biz
{
public override string hi()
{
return "hello world! I'm biz1.";
}
}
public class Biz2 : Biz
{
public override string hi()
{
return "hello world! I'm biz2.";
}
}
public class Biz3 : Biz
{
public override string hi()
{
return "hello world! I'm biz3.";
}
}
// DemoFactory
public class DemoFactory : MarshalByRefObject
{
public Demo getDemo1()
{
return new Demo1();
}
public Demo getDemo2()
{
return new Demo2();
}
public Demo getDemo3()
{
return new Demo3();
}
}
// abstruct class Demo
public abstract class Demo : MarshalByRefObject
{
public Demo()
{
Console.WriteLine("Demo construct.");
}
~Demo()
{
Console.WriteLine("Demo destory.");
}
public abstract string where();
}
public class Demo1 : Demo
{
public override string where()
{
return "Demo1: I'm here.";
}
}
public class Demo2 : Demo
{
public override string where()
{
return "Demo2: I'm here.";
}
}
public class Demo3 : Demo
{
public override string where()
{
return "Demo3: I'm here.";
}
}
}
namespace Business
{
// bizFactory
public class bizFactory : MarshalByRefObject
{
public Biz getbiz1()
{
return new Biz1();
}
public Biz getbiz2()
{
return new Biz2();
}
public Biz getbiz3()
{
return new Biz3();
}
}
// abstruct class Biz
public abstract class Biz : MarshalByRefObject
{
public Biz()
{
Console.WriteLine("biz construct.");
}
~Biz()
{
Console.WriteLine("biz destory.");
}
public abstract string hi();
}
public class Biz1 : Biz
{
public override string hi()
{
return "hello world! I'm biz1.";
}
}
public class Biz2 : Biz
{
public override string hi()
{
return "hello world! I'm biz2.";
}
}
public class Biz3 : Biz
{
public override string hi()
{
return "hello world! I'm biz3.";
}
}
// DemoFactory
public class DemoFactory : MarshalByRefObject
{
public Demo getDemo1()
{
return new Demo1();
}
public Demo getDemo2()
{
return new Demo2();
}
public Demo getDemo3()
{
return new Demo3();
}
}
// abstruct class Demo
public abstract class Demo : MarshalByRefObject
{
public Demo()
{
Console.WriteLine("Demo construct.");
}
~Demo()
{
Console.WriteLine("Demo destory.");
}
public abstract string where();
}
public class Demo1 : Demo
{
public override string where()
{
return "Demo1: I'm here.";
}
}
public class Demo2 : Demo
{
public override string where()
{
return "Demo2: I'm here.";
}
}
public class Demo3 : Demo
{
public override string where()
{
return "Demo3: I'm here.";
}
}
}
ClassFactory.cs
using
System;
using System.Xml;
using System.Configuration;
using SAF.Configuration;
namespace SAF.ClassFactory
{
/// <summary>
/// class factory service, used to obtain the abstract factory class.
/// </summary>
public class ClassFactory : MarshalByRefObject
{
/// <summary>
/// Called by the client to get an instance of the factory class
/// </summary>
/// <param name="factoryName">factory name</param>
/// <returns>class factory object</returns>
public object GetFactory(string factoryName)
{
object factory = null;
SAF.Configuration.ConfigurationManager cm = (SAF.Configuration.ConfigurationManager)ConfigurationSettings.GetConfig("Framework");
ClassFactoryConfiguration cf= cm.ClassFactoryConfig;
XmlNode classFactoryData = cf.GetFactoryData(factoryName);
//obtain the type information
string type = classFactoryData.Attributes["type"].Value;
Type t = System.Type.GetType(type);
//creat an instance of concrete class factory
if (classFactoryData.Attributes["location"] != null)
{
string location = classFactoryData.Attributes["location"].Value;
factory = Activator.GetObject(t,location);
}
else
{
factory = Activator.CreateInstance(t,null);
}
return factory;
}
}
}
using System.Xml;
using System.Configuration;
using SAF.Configuration;
namespace SAF.ClassFactory
{
/// <summary>
/// class factory service, used to obtain the abstract factory class.
/// </summary>
public class ClassFactory : MarshalByRefObject
{
/// <summary>
/// Called by the client to get an instance of the factory class
/// </summary>
/// <param name="factoryName">factory name</param>
/// <returns>class factory object</returns>
public object GetFactory(string factoryName)
{
object factory = null;
SAF.Configuration.ConfigurationManager cm = (SAF.Configuration.ConfigurationManager)ConfigurationSettings.GetConfig("Framework");
ClassFactoryConfiguration cf= cm.ClassFactoryConfig;
XmlNode classFactoryData = cf.GetFactoryData(factoryName);
//obtain the type information
string type = classFactoryData.Attributes["type"].Value;
Type t = System.Type.GetType(type);
//creat an instance of concrete class factory
if (classFactoryData.Attributes["location"] != null)
{
string location = classFactoryData.Attributes["location"].Value;
factory = Activator.GetObject(t,location);
}
else
{
factory = Activator.CreateInstance(t,null);
}
return factory;
}
}
}
remotingserver.cs
using
System;
using System.Runtime.Remoting;
namespace RemotingServer
{
public class Program
{
public static void Main()
{
RemotingConfiguration.Configure("remotingserver.exe.Config");
Console.WriteLine("service started.");
Console.WriteLine("press any key to exit application.");
Console.ReadLine();
}
}
}
using System.Runtime.Remoting;
namespace RemotingServer
{
public class Program
{
public static void Main()
{
RemotingConfiguration.Configure("remotingserver.exe.Config");
Console.WriteLine("service started.");
Console.WriteLine("press any key to exit application.");
Console.ReadLine();
}
}
}
remotingserver.exe.Config
<?
xml version="1.0" encoding="utf-8"
?>
< configuration >
< configSections >
< section name ="Framework" type ="SAF.Configuration.ConfigurationHandler,SAF.Configuration" />
</ configSections >
< Framework type ="SAF.Configuration.ConfigurationManager,SAF.Configuration" >
< SAF .ClassFactory >
< Class name ="bizFactory" type ="Business.bizFactory, Business" />
< Class name ="DemoFactory" type ="Business.DemoFactory, Business" />
</ SAF.ClassFactory >
</ Framework >
< system .runtime.remoting >
< application name ="remotingserver" >
< service >
< wellknown mode ="SingleCall" type ="SAF.ClassFactory.ClassFactory, ClassFactory"
objectUri ="ClassFactory.rem" />
</ service >
< channels >
< channel ref ="http" port ="8989" />
</ channels >
</ application >
</ system.runtime.remoting >
</ configuration >
< configuration >
< configSections >
< section name ="Framework" type ="SAF.Configuration.ConfigurationHandler,SAF.Configuration" />
</ configSections >
< Framework type ="SAF.Configuration.ConfigurationManager,SAF.Configuration" >
< SAF .ClassFactory >
< Class name ="bizFactory" type ="Business.bizFactory, Business" />
< Class name ="DemoFactory" type ="Business.DemoFactory, Business" />
</ SAF.ClassFactory >
</ Framework >
< system .runtime.remoting >
< application name ="remotingserver" >
< service >
< wellknown mode ="SingleCall" type ="SAF.ClassFactory.ClassFactory, ClassFactory"
objectUri ="ClassFactory.rem" />
</ service >
< channels >
< channel ref ="http" port ="8989" />
</ channels >
</ application >
</ system.runtime.remoting >
</ configuration >
ClientClassFactory.cs
using
System;
using System.Xml;
using System.Configuration;
using SAF.ClassFactory;
namespace Client
{
/// <summary>
/// class factory service, used to obtain the abstract factory class.
/// </summary>
public class ClientClassFactory
{
private static ClassFactory remoteFactory;
/// <summary>
/// Called by the client to get an instance of the factory class
/// </summary>
/// <param name="factoryName">factory name</param>
/// <returns>class factory object</returns>
public static object GetFactory(string factoryName)
{
if (remoteFactory == null)
{
remoteFactory = new ClassFactory();
}
return remoteFactory.GetFactory(factoryName);
}
}
}
using System.Xml;
using System.Configuration;
using SAF.ClassFactory;
namespace Client
{
/// <summary>
/// class factory service, used to obtain the abstract factory class.
/// </summary>
public class ClientClassFactory
{
private static ClassFactory remoteFactory;
/// <summary>
/// Called by the client to get an instance of the factory class
/// </summary>
/// <param name="factoryName">factory name</param>
/// <returns>class factory object</returns>
public static object GetFactory(string factoryName)
{
if (remoteFactory == null)
{
remoteFactory = new ClassFactory();
}
return remoteFactory.GetFactory(factoryName);
}
}
}
Client.cs
using
System;
using System.Runtime.Remoting;
using Client;
using Business;
namespace Client
{
public class Client
{
public static void Main()
{
RemotingConfiguration.Configure("Client.Config");
bizFactory bizFactory = (bizFactory)ClientClassFactory.GetFactory("bizFactory");
DemoFactory demoFactory= (DemoFactory)ClientClassFactory.GetFactory("DemoFactory");
Biz biz1 = bizFactory.getbiz1();
Biz biz2 = bizFactory.getbiz2();
Biz biz3 = bizFactory.getbiz3();
Demo demo1 = demoFactory.getDemo1();
Demo demo2 = demoFactory.getDemo2();
Demo demo3 = demoFactory.getDemo3();
Console.WriteLine(biz1.hi());
Console.WriteLine(biz2.hi());
Console.WriteLine(biz3.hi());
Console.WriteLine(demo1.where());
Console.WriteLine(demo2.where());
Console.WriteLine(demo3.where());
Console.ReadLine();
}
}
}
using System.Runtime.Remoting;
using Client;
using Business;
namespace Client
{
public class Client
{
public static void Main()
{
RemotingConfiguration.Configure("Client.Config");
bizFactory bizFactory = (bizFactory)ClientClassFactory.GetFactory("bizFactory");
DemoFactory demoFactory= (DemoFactory)ClientClassFactory.GetFactory("DemoFactory");
Biz biz1 = bizFactory.getbiz1();
Biz biz2 = bizFactory.getbiz2();
Biz biz3 = bizFactory.getbiz3();
Demo demo1 = demoFactory.getDemo1();
Demo demo2 = demoFactory.getDemo2();
Demo demo3 = demoFactory.getDemo3();
Console.WriteLine(biz1.hi());
Console.WriteLine(biz2.hi());
Console.WriteLine(biz3.hi());
Console.WriteLine(demo1.where());
Console.WriteLine(demo2.where());
Console.WriteLine(demo3.where());
Console.ReadLine();
}
}
}
Client.Config
<?
xml version="1.0" encoding="utf-8"
?>
< configuration >
< system .runtime.remoting >
< application name ="Client" >
< client >
< wellknown type ="SAF.ClassFactory.ClassFactory, ClassFactory"
url ="http://localhost:8989/remotingserver/ClassFactory.rem" />
</ client >
</ application >
</ system.runtime.remoting >
</ configuration >
< configuration >
< system .runtime.remoting >
< application name ="Client" >
< client >
< wellknown type ="SAF.ClassFactory.ClassFactory, ClassFactory"
url ="http://localhost:8989/remotingserver/ClassFactory.rem" />
</ client >
</ application >
</ system.runtime.remoting >
</ configuration >
客户端执行时的错误信息:
未处理的异常: System.NullReferenceException: 未将对象引用设置到对象的实例。
Server stack trace:
在 SAF.ClassFactory.ClassFactory.GetFactory(String factoryName)
在 System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(
IntPtr md , Object [] args , Object server , Int32 methodPtr , Boolean fExecuteInCont
ext , Object [] & outArgs)
在 System.Runtime.Remoting.Messaging.StackBuilderSink.PrivateProcessMessage(R
untimeMethodHandle md , Object [] args , Object server , Int32 methodPtr , Boolean fE
xecuteInContext , Object [] & outArgs)
在 System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMes
sage msg , Int32 methodPtr , Boolean fExecuteInContext)
Exception rethrown at [ 0 ] :
在 System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage req
Msg , IMessage retMsg)
在 System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgDa
ta , Int32 type)
在 SAF.ClassFactory.ClassFactory.GetFactory(String factoryName)
在 Client.ClientClassFactory.GetFactory(String factoryName)
在 Client.Client.Main()
Server stack trace:
在 SAF.ClassFactory.ClassFactory.GetFactory(String factoryName)
在 System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(
IntPtr md , Object [] args , Object server , Int32 methodPtr , Boolean fExecuteInCont
ext , Object [] & outArgs)
在 System.Runtime.Remoting.Messaging.StackBuilderSink.PrivateProcessMessage(R
untimeMethodHandle md , Object [] args , Object server , Int32 methodPtr , Boolean fE
xecuteInContext , Object [] & outArgs)
在 System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMes
sage msg , Int32 methodPtr , Boolean fExecuteInContext)
Exception rethrown at [ 0 ] :
在 System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage req
Msg , IMessage retMsg)
在 System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgDa
ta , Int32 type)
在 SAF.ClassFactory.ClassFactory.GetFactory(String factoryName)
在 Client.ClientClassFactory.GetFactory(String factoryName)
在 Client.Client.Main()