wcf CS0012拼图嵌套类型

时间:2016-09-06 04:32:34

标签: c# wcf datacontract

很抱歉,如果这很明显,但我正在解决这个问题:我有一个定义Class1的类库ClassLibrary1,以及一个引用ClassLibrary1的WCF服务库WcfServiceLibrary1,它定义了一个类Response in哪个Class1是嵌套的:

    public class Response
{
    public string Message { get; set; }
    public Class1 Value { get; set; }
}

然后我添加了一个简单的控制台应用程序作为客户端引用WcfServiceLibrary1(但不是ClassLibrary1,以模拟业务逻辑和客户端逻辑之间的分离)。但是我无法编译WcfServiceLibrary1,因为我收到错误“CS0012类型'Class1'是在未引用的程序集中定义的。您必须添加对程序集'ClassLibrary1 ...'的引用。

我错过了什么?感谢

的Class1.cs:

namespace ClassLibrary1
{
    public class Class1
    {
        public int SomeInt { get; set; }
    }
}

IService1.cs:

namespace WcfServiceLibrary1
{
    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        Response ConvertToClass(int value);

        [OperationContract]
        Class1 AltConvertToClass(int value);
    }

    public class Response
    {
        public string Message { get; set; }
        public Class1 Value { get; set; }
    }
}

Service1.cs:

namespace WcfServiceLibrary1
{
    public class Service1 : IService1
    {
        public Response ConvertToClass(int value)
        {
            return new Response() {Message = "Success", Value = new Class1() {SomeInt = value}};
        }

        public Class1 AltConvertToClass(int value)
        {
            return new Class1() {SomeInt = value};
        }
    }
}

的Program.cs:

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var client = new ServiceReference1.Service1Client();
            client.Open();

            Console.Write("Enter number:");
            var s = Console.ReadLine();

            var n = int.Parse(s);

            var c = client.ConvertToClass(n);
            Console.WriteLine($"Result: Message = {c.Message}, Value = {c.Value}"); //CS0012
            var c2 = client.AltConvertToClass(n);
            Console.WriteLine($"Result: {c2.SomeInt}");

            Console.WriteLine("\nPress enter...");
            Console.ReadLine();
        }
    }
}

3 个答案:

答案 0 :(得分:0)

错误说的正是如此。

无论您的设计意图如何,通过引用Class1中的WcfServiceLibrary1,您已使ClassLibrary1成为WcfServiceLibrary1的依赖关系。

在没有引用WcfServiceLibrary1的情况下,没有其他组件可以引用ClassLibrary1

您必须重新审视您的设计。

答案 1 :(得分:0)

更新1

查看解决方案后,问题是您正在生成服务引用,该引用会创建服务所需的类的副本。打开ConsoleApplication1 - >服务参考 - > ServiceReference1 - > Reference.svcmap - > Reference.cs,您将看到它在名称空间Class1中生成了一个名为ConsoleApplication1.ServiceReference1的类。这样做是因为项目没有引用您的ClassLibrary1解决方案。它没有生成Response对象的代码,因为它已在您的控制台项目中引用。结果是:

  1. 致电AltConvertToClass会返回ConsoleApplication1.ServiceReference1.Class1
  2. 类型的对象
  3. 调用ConvertToClass返回类型为WcfServiceLibrary1.Response的对象,其中包含ClassLibrary1.Class1类型的对象(与上面的对象不同),导致编译器错误
  4. 我建议你按照下面链接的教程,因为恕我直言是正确的面向服务架构的方法。单独保留服务引用 - 它最终会复制代码。

    否则,您可以按如下方式修改代码:

    1. 创建合同项目并移动界面(IService1)和DTO(您的Response类是DTO,当您返回Class1时,也是DTO)这个项目。
    2. 包含实施(Service1)的服务项目应该引用您的合同类
    3. 控制台应用程序应引用您的合同项目
    4. 更新您的服务参考
    5. <强>原始

      您仍然需要引用您使用其类的任何项目。由于您的控制台应用程序中使用了Class1,因此需要引用ClassLibrary1

      如果要将业务逻辑与客户端应用程序分开,则不能在客户端应用程序中引用业务逻辑类中的任何类。如果要返回Response类中的任何对象,则应该创建一个包含DTO(数据传输对象)的合同库,并将域类映射到DTO类,并在两者中引用合同项目。服务器和客户端。

      前一段时间我在http://lourenco.co.za/blog/2013/08/wcf-windows-service-using-topshelf-and-servicemodelex/写了一篇关于这个架构的教程。 免责声明 - 我写了这个教程!

答案 2 :(得分:0)

此错误来自ConsoleApplication1(客户端)引用WcfServiceLibrary1(主机),导致[ConsoleApplication1 - &gt;中自动生成的服务代码服务参考 - &gt; ServiceReference1 - &gt; Reference.svcmap - &gt; Reference.cs]重用WcfServiceLibrary1.Response(依赖ClassLibrary1.Class1从而CS0012),否则创建ServiceReference1.Class1来处理AltConvertToClass方法。

解决方案是将ConsoleApplication1(客户端)的引用移除到WcfServiceLibrary1(主机),这非常有意义,因为两个程序集通常会在不同的计算机上运行。

感谢大家的贡献!