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

时间:2009-05-30 17:05:18

标签: wcf

VS WCF集成有很好的选择“在refrenced程序集中重用类型”。问题是我需要相同的但是对于当前的组件。我的程序集中已经定义了一些类型,我需要重用它们。

使用场景:

  1. 我有集会,并且在这里有TypeA。
  2. 我添加了服务引用,其中一个方法返回与TypeA完全兼容的类型(属性,名称)。
  3. 添加服务引用会生成代理,但会在其中重新创建新的TypeA。
  4. 在第3步,我需要会返回TypeA的代理。不是新的TypeA。

3 个答案:

答案 0 :(得分:12)

如果我理解你想要做什么,那么这是我经常遇到的一个场景,而且,WCF确实有一个不错的答案:只是不要使用SvcUtil / WS服务参考向导。

如果您已经在客户端定义了大部分合同类(因为您有共享程序集,或者因为您在项目中定义了相应的类),那么您也可以继续执行下一步,以代码形式导入完整的服务合同,或者只是在客户端重新定义它。

没有什么可以强迫你使用svcutil和朋友,只需定义你的界面并直接使用频道模型(即ChannelFactory< T>和朋友),或者,如果你更喜欢使用代理类,只需创建你自己的ClientBase< T> - 来自类。它真的很容易,从长远来看它可以帮你省去。

答案 1 :(得分:6)

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

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

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

答案 2 :(得分:0)

我遇到了同样的问题,我希望测试工具指向一些服务。每项服务都有共同的数据交换。

需要做什么:

  1. 在每个网址上使用带/ t:元数据的svcutil。
  2. 使用服务的唯一内容重命名所有生成的文件(例如,将lala.xsd重命名为1_lala.xsd)
  3. 将所有生成的文件复制到一个位置
  4. 将svcutil与* .xsd .wsdl /out:output.cs / namespace:,MySpecialNamespace一起使用,以生成所有服务合同和数据到单个文件。
  5. 如果你想变得狡猾:使用以下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;
    }
    #>