设计模式学习——动态代理实现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,如需转载请自行联系原作者

相关文章
|
7天前
|
设计模式 缓存 应用服务中间件
「全网最细 + 实战源码案例」设计模式——外观模式
外观模式(Facade Pattern)是一种结构型设计模式,旨在为复杂的子系统提供一个统一且简化的接口。通过封装多个子系统的复杂性,外观模式使外部调用更加简单、易用。例如,在智能家居系统中,外观类可以同时控制空调、灯光和电视的开关,而用户只需发出一个指令即可。
110 69
|
2月前
|
Java 物联网 C#
C#/.NET/.NET Core学习路线集合,学习不迷路!
C#/.NET/.NET Core学习路线集合,学习不迷路!
103 0
|
20天前
|
存储 设计模式 算法
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。行为型模式分为类行为模式和对象行为模式,前者采用继承机制来在类间分派行为,后者采用组合或聚合在对象间分配行为。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。 行为型模式分为: • 模板方法模式 • 策略模式 • 命令模式 • 职责链模式 • 状态模式 • 观察者模式 • 中介者模式 • 迭代器模式 • 访问者模式 • 备忘录模式 • 解释器模式
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
|
20天前
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性。 结构型模式分为以下 7 种: • 代理模式 • 适配器模式 • 装饰者模式 • 桥接模式 • 外观模式 • 组合模式 • 享元模式
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
|
20天前
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
创建型模式的主要关注点是“怎样创建对象?”,它的主要特点是"将对象的创建与使用分离”。这样可以降低系统的耦合度,使用者不需要关注对象的创建细节。创建型模式分为5种:单例模式、工厂方法模式抽象工厂式、原型模式、建造者模式。
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
|
3月前
|
设计模式 网络协议 Java
06.动态代理设计模式
本文详细介绍了动态代理设计模式,包括其必要性、概念、实现方式及案例分析。动态代理允许在运行时动态创建代理对象,增强代码复用性和灵活性,减少类膨胀。文章通过对比静态代理,深入解析了动态代理的实现机制,如基于接口和类的动态代理,以及其在Retrofit中的应用。同时,讨论了动态代理的优势和潜在问题,如性能开销和调试难度。最后,提供了丰富的学习资源链接,帮助读者进一步理解和掌握动态代理。
28 1
|
4月前
|
设计模式 Java 关系型数据库
【Java笔记+踩坑汇总】Java基础+JavaWeb+SSM+SpringBoot+SpringCloud+瑞吉外卖/谷粒商城/学成在线+设计模式+面试题汇总+性能调优/架构设计+源码解析
本文是“Java学习路线”专栏的导航文章,目标是为Java初学者和初中高级工程师提供一套完整的Java学习路线。
508 37
|
3月前
|
设计模式 安全 Java
C# 一分钟浅谈:设计模式之单例模式
【10月更文挑战第9天】单例模式是软件开发中最常用的设计模式之一,旨在确保一个类只有一个实例,并提供一个全局访问点。本文介绍了单例模式的基本概念、实现方式(包括饿汉式、懒汉式和使用 `Lazy<T>` 的方法)、常见问题(如多线程和序列化问题)及其解决方案,并通过代码示例详细说明了这些内容。希望本文能帮助你在实际开发中更好地应用单例模式,提高代码质量和可维护性。
96 1
|
3月前
|
开发框架 缓存 算法
开源且实用的C#/.NET编程技巧练习宝库(学习,工作,实践干货)
开源且实用的C#/.NET编程技巧练习宝库(学习,工作,实践干货)
|
4月前
|
设计模式 C# 开发者
C#设计模式入门实战教程
C#设计模式入门实战教程