91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

設計模式學習——動態代理實現C#動態調用WebService(附源碼)

發布時間:2020-04-07 23:42:50 來源:網絡 閱讀:5502 作者:HDDevTeam 欄目:編程語言

對于這個問題,很很早以前就遇到了,當時并不理解。前段時間看了一下動態代理,對這個問題有了一些了解。

對于一般的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);

這樣就將代理類加載到了內存當中,并且長生了一個實例,將這個實例返回就可以根據他來調用所需的方法了。當然調用方法時可能還是要用到反射,因為已知的可能僅僅只有方法名和它所需的參數。

更多詳細內容請查看本文源碼。

附件:http://down.51cto.com/data/2358642
向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

汕尾市| 广昌县| 鲁山县| 威宁| 小金县| 富蕴县| 乡城县| 兰州市| 巴林右旗| 崇礼县| 罗平县| 北安市| 巴马| 冀州市| 永登县| 淅川县| 弥渡县| 林西县| 逊克县| 溧阳市| 广安市| 宁南县| 资中县| 扶风县| 西乡县| 沙田区| 陇南市| 吴堡县| 永寿县| 汉川市| 永泰县| 印江| 仪陇县| 诸暨市| 五原县| 乐山市| 贵溪市| 元江| 淄博市| 巴彦县| 蓝田县|