应用框架的设计与实现——.NET平台(4.3 SAF代码分析.源码2)


按照<图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.";
        }

    }

}


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;
        }

    }

}



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();
        }

    }

}


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 >


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);
        }

    }

}

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();
        }

    }

}

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 >


客户端执行时的错误信息:
未处理的异常:  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()
Free Spire.PDF for .NET 是 Spire.PDF for .NET 的免费版本,无需购买即可用于个人或商业用途。使用该组件,程序员可以 在.NET 程序中创建、读取、写入、编辑和操作 PDF 文档。这个控件能支持的功能十分全面,例如文档安全性设置(电子签名),提取 PDF 文本、附件、图片,PDF 合并和拆分,更新 Metadata,设置 Section,绘制图形、插入图片、表格制作和加工、导入数据等等。除此以外,Spire.PDF 还可以将 TXT 文本、图片、HTML 高质量地转换为 PDF 文件格式。 主要功能如下: 1.高质量的文档转换。Free Spire.PDF for .NET 支持 PDF 到 Word、XPS、SVG、EMF、Text 和图片(EMF、JPG、PNG、BMP、TIFF)的格式转换。也支持从 XML、HTML、RTF、XPS、Text、图片等格式生成 PDF 文档。 2.文档操作及域功能。支持合并、拆分 PDF 文档,在原有的 PDF 文档页添加覆盖页。同时,Spire.PDF 提供导入、邮戳、小册子功能,以及帮助用户从数据库读取数据并填充到域的域填写功能。 3. 安全性设置。用户可以通过设置密码和数字签名来保护 PDF 文档。用户密码和所有者密码可以确定加密的 PDF 文档的可读性、可修改性、是否可打印等有选择性的限制。与此同时,数字签名作为一个更有效的方法,可以应用于维护和对PDF文档进行身份验证。 4.数据提取。支持快速高效地从 PDF 文档提取图片、文本、PDF 分页,以及附件。 5.文件属性设置。支持对 Metadata、文件属性、页面方向、页面大小进行设置。其中文件属性包括文件限制(打印、页面提取、加评论等方面的权限限制)以及文件描述属性(文件名称、作者、主题、关键字等)。使用 Spire.PDF for .NET,用户还可以根据自己阅读喜好设定默认打开页码,分页模式,缩放比例和打印缩放,等等。 6.其他功能。 支持多种语言,支持字体格式、对齐方式设置。 绘制文字,图片,图形。 支持添加图层,透明图像,Color Space,条形码到 PDF。 支持 PDF/A-1b、PDF/x1a:2001 格式。 添加梯状图形和矢量图像到指定位置。 添加并格式化表格。 插入交互元素,例如添加自定义的 Annotation、Action、JavaScript、附件、书签等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值