代码之家  ›  专栏  ›  技术社区  ›  Mike Chaliy

为WCF代理重用当前程序集中的类型

wcf
  •  10
  • Mike Chaliy  · 技术社区  · 15 年前

    VS WCF集成有一个不错的选项“在引用的程序集中重用类型”。问题是,除了当前的程序集,我还需要相同的程序集。有些类型已经在我的程序集中定义,我需要重用它们。

    使用场景:

    1. 我有装配,这里有A型。
    2. 我为它添加了服务引用,其中一个方法返回与类型A(属性、名称)完全兼容的类型。
    3. 添加服务引用会生成代理,但它会在中重新创建新的typea。

    在步骤3中,我需要返回typea的代理。不是新TypeA。

    3 回复  |  直到 12 年前
        1
  •  12
  •   tomasr    15 年前

    如果我理解您想要做什么,那么这是我经常遇到的一个场景,而且,wcf确实有一个不错的答案:不要使用svcutil/ws服务引用向导。

    如果您的客户机端已经定义了大部分契约类(可能是因为您有一个共享程序集,或者是因为您在项目上定义了等价的类),那么您也可以进入下一步,以代码形式导入完整的服务契约,或者在客户机端简单地重新定义它。

    没有什么能强迫您使用svcutil和friends,只需定义您的接口,直接使用通道模型(即channelFactory和friends),或者,如果您喜欢使用代理类,只需创建自己的clientBase派生类即可。这真的很容易,从长远来看,它可以帮你省事。

        2
  •  6
  •   Walter Almeida    14 年前

    有一种简单的方法可以在客户端和服务之间共享类型,只需在添加服务引用之前向客户端添加对共享类型程序集的引用即可。

    您可以在那里找到详细的场景和示例项目:

    http://blog.walteralmeida.com/2010/08/wcf-tips-and-tricks-share-types-between-server-and-client.html

        3
  •  0
  •   Arnaud    12 年前

    我也遇到了同样的问题,我需要一个测试工具来指向几个服务。每个服务都有相同的数据契约。

    需要做的:

    1. 在每个URL上使用svcutil和/t:metadata。
    2. 用服务特有的东西重命名所有生成的文件(例如,将lala.xsd重命名为1_lala.xsd)
    3. 将所有生成的文件复制到单个位置
    4. 将svcutil与*.xsd一起使用 .wsdl/out:output.cs/命名空间: ,MySpecialNamespace,用于生成单个文件的所有服务合同和数据合同。

    如果你想变得狡猾:使用下面的t4模板:

    <#@ template language="C#v4.0" hostspecific="True"#>
    <#@ import namespace="System.Diagnostics" #>
    <#@ import namespace="System.IO" #>
    <#=GetGeneratedCode(
    "http://localhost/Service/Service1.svc",
    "http://localhost/Service/Service2.svc",
    "http://localhost/Service/Service3.svc",
    "http://localhost/Service/Service4.svc"
    )#>
    <#+
    const string _svcutil = @"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\svcutil.exe";
    
    private string GetGeneratedCode(params string[] urls)
    {
        var tmp = GetTemporaryDirectory();
        foreach (var url in urls)
        {
            GetMetadata(url, tmp);
        }
    
        RunSvcutil(tmp, "*.wsdl *.xsd /out:output.cs /namespace:*," +     Path.GetFileNameWithoutExtension(Host.TemplateFile));
        var result = File.ReadAllText(Path.Combine(tmp, "output.cs"));
        return result;
    }
    
    private static void RunSvcutil(string workingFolder, string arguments)
    {
        var processInfo = new ProcessStartInfo(_svcutil);
        processInfo.Arguments = arguments;
        processInfo.WorkingDirectory = workingFolder;
    
        var p = Process.Start(processInfo);
        p.WaitForExit();
    }
    
    private static void GetMetadata(string url, string destination)
    {
        var workingFolder = GetTemporaryDirectory();
        RunSvcutil(workingFolder, string.Format("/t:metadata \"{0}\"", url));
    
        foreach (var filename in Directory.GetFiles(workingFolder))
        {
            File.Copy(filename, Path.Combine(destination,     Path.GetFileNameWithoutExtension(url) + "_" +  Path.GetFileName(filename)));
        }
    }
    
    private static string GetTemporaryDirectory()
    {
        string tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
        Directory.CreateDirectory(tempDirectory);
        return tempDirectory;
    }
    #>