设计模式学习——动态代理实现C#动态调用WebService(附源码)

简介:

对于这个问题,很很早以前就遇到了,当时并不理解。前段时间看了一下动态代理,对这个问题有了一些了解。

对于一般的webservice,可以通过添加web引用实现调用。但这样的缺点就是不够灵活,当webservice地址发生变化时需要重新添加引用,重新编译。这种缺点还稍微可以接受的。我遇到的应用场景是,程序运行之前无法知道webservice的地址,因为地址都存放于数据库中,使用时需要动态的调用。这样通过添加引用基本不可能实现,所以采用上述方法实现。

在采用这种方法时,首先遇到的问题就是:如何构造的代理类?

类似于javaJDK提供的有编译源文件的接口,.net也提供的有相关的类似的我们能够动态的生成源码并进行编译,从而动态的生成代理类。(当然不排除大牛通过解析语法规则直接生成二进制文件,而无需调用编译接口的。)

我们可以采用类似于下面的方法来动态的生成要编译的源码。

private CodeCompileUnit GetServiceCompileUnit(string webServiceUrl)

    {

        WebClient client = new WebClient();

        Stream stream = client.OpenRead(webServiceUrl);

//从这个url指向的的是一个xml文件,里面包含了该service的全部信息。

//进而通过解析xml文件从而可以生成要编译的源码。有兴趣的可以看一下xml的内容

ServiceDescription description = ServiceDescription.Read(stream);        ServiceDescriptionImporter importer = new ServiceDescriptionImporter();        importer.ProtocolName = "Soap";//使用的协议

        importer.Style = ServiceDescriptionImportStyle.Client;

importer.CodeGenerationOptions = CodeGenerationOptions.GenerateProperties | CodeGenerationOptions.GenerateNewAsync;

importer.AddServiceDescription(description, """");  

     CodeNamespace nmspace = new CodeNamespace();

        nmspace.Name = "WebService";//生成类的名空间,可以根据需求指定

        CodeCompileUnit unit = new CodeCompileUnit();

        unit.Namespaces.Add(nmspace);

        ServiceDescriptionImportWarnings warning = importer.Import(nmspace, unit);

        return unit;

    }

Unit返回的就是要进行编译的东西了。

 

下一步及时进行编译了。根据需求设置相关的编译参数后,就就可以进行编译了。就像下边这样。

 

 

 private CompilerResults Compile(CodeCompileUnit unit)

    {

        CodeDomProvider codeDomProvider = CodeDomProvider.CreateProvider("CSharp");

        CompilerParameters compilerParameters = new CompilerParameters();

        compilerParameters.GenerateExecutable = false;

        compilerParameters.GenerateInMemory = true;

   //  cp.OutputAssembly = "D:\\Test.dll";这里也可以将变异的结果输出到dll文件中,从而可以查看编译的的结果。有兴趣的自己看一下。

     compilerParameters.ReferencedAssemblies.Add("System.dll");

        compilerParameters.ReferencedAssemblies.Add("System.XML.dll");

        compilerParameters.ReferencedAssemblies.Add("System.Web.Services.dll");

        compilerParameters.ReferencedAssemblies.Add("System.Data.dll");

  CompilerResults compilerResults = codeDomProvider.CompileAssemblyFromDom(compilerParameters, unit);

        if (compilerResults.Errors.HasErrors)

        {

            string errors = "";

            foreach (var item in compilerResults.Errors)

            {

                errors += item.ToString() + Environment.NewLine;

            }

            throw new Exception("Compile error:" + errors);

        }

        return compilerResults;

    }

 

有了编译的结果,已经生成了代理类,下一步要做的就是将这个代理类加载到内存当中。

   Assembly asm = result.CompiledAssembly;

        object obj = asm.CreateInstance("WebService." + proxy._className);

这样就将代理类加载到了内存当中,并且长生了一个实例,将这个实例返回就可以根据他来调用所需的方法了。当然调用方法时可能还是要用到反射,因为已知的可能仅仅只有方法名和它所需的参数。




本文转自HDDevTeam 51CTO博客,原文链接:http://blog.51cto.com/hddev/628288,如需转载请自行联系原作者

相关文章
|
11天前
|
开发框架 前端开发 JavaScript
C# 6.0+JavaScript云LIS系统源码  云LIS实验室信息管理新型解决方案
云LIS是为区域医疗提供临床实验室信息服务的计算机应用程序,可协助区域内所有临床实验室相互协调并完成日常检验工作,对区域内的检验数据进行集中管理和共享,通过对质量控制的管理,最终实现区域内检验结果互认。其目标是以医疗服务机构为主体,以医疗资源和检验信息共享为目标,集成共性技术及医疗服务关键技术,建立区域协同检验,最大化利用有限的医疗卫生资源。
23 1
|
4天前
|
设计模式 安全 Java
【初学者慎入】Spring源码中的16种设计模式实现
以上是威哥给大家整理了16种常见的设计模式在 Spring 源码中的运用,学习 Spring 源码成为了 Java 程序员的标配,你还知道Spring 中哪些源码中运用了设计模式,欢迎留言与威哥交流。
|
7天前
|
存储 数据采集 安全
C#医院手术室麻醉信息管理系统源码 自动生成麻醉的各种医疗文书(手术风险评估表、手术安全核查表)
医院手术麻醉信息系统有着完善的临床业务功能,能够涵盖整个围术期的工作,能够采集、汇总、存储、处理、展现所有的临床诊疗资料。通过该系统的实施,能够规范麻醉科的工作流程,实现麻醉手术过程的信息数字化,自动生成麻醉的各种医疗文书,完成共享HIS、LIS、PACS和EMR等手术患者信息,从而提高麻醉、手术工作的管理水平。
19 3
|
10天前
|
设计模式 算法 Java
[设计模式Java实现附plantuml源码~行为型]定义算法的框架——模板方法模式
[设计模式Java实现附plantuml源码~行为型]定义算法的框架——模板方法模式
|
10天前
|
设计模式 JavaScript Java
[设计模式Java实现附plantuml源码~行为型] 对象状态及其转换——状态模式
[设计模式Java实现附plantuml源码~行为型] 对象状态及其转换——状态模式
|
10天前
|
设计模式 存储 Java
[设计模式Java实现附plantuml源码~结构型]实现对象的复用——享元模式
[设计模式Java实现附plantuml源码~结构型]实现对象的复用——享元模式
|
10天前
|
设计模式 JavaScript Java
[设计模式Java实现附plantuml源码~结构型]处理多维度变化——桥接模式
[设计模式Java实现附plantuml源码~结构型]处理多维度变化——桥接模式
|
10天前
|
设计模式 Java Go
[设计模式Java实现附plantuml源码~结构型]不兼容结构的协调——适配器模式
[设计模式Java实现附plantuml源码~结构型]不兼容结构的协调——适配器模式
|
10天前
|
设计模式 JavaScript Java
[设计模式Java实现附plantuml源码~结构型]对象的间接访问——代理模式
[设计模式Java实现附plantuml源码~结构型]对象的间接访问——代理模式
|
10天前
|
设计模式 安全 Java
[设计模式Java实现附plantuml源码~结构型]树形结构的处理——组合模式
[设计模式Java实现附plantuml源码~结构型]树形结构的处理——组合模式