wcf CS0012 嵌套类型拼图

wcf CS0012 puzzle with nested type

很抱歉,如果这很明显,但我正在解决这个问题:我有一个定义 Class1 的 class 库 ClassLibrary1,以及一个引用定义 Class1 的 ClassLibrary1 的 WCF 服务库 WcfServiceLibrary1 =36=] Response 其中嵌套了Class1:

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

然后我添加了一个简单的控制台应用程序作为客户端引用 WcfServiceLibrary1(但不是 ClassLibrary1,以模拟业务逻辑和客户端逻辑之间的分离)。但是我无法编译 WcfServiceLibrary1,因为我收到错误 "CS0012 The type 'Class1' is defined in an assembly that is not referenced. You must add a reference to assembly '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();
        }
    }
}

正是错误所说的。

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

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

您将不得不重新审视您的设计。

更新 1

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

  1. 调用AltConvertToClassreturn是一个ConsoleApplication1.ServiceReference1.Class1
  2. 类型的对象
  3. 调用ConvertToClass returns一个WcfServiceLibrary1.Response类型的对象,其中包含一个ClassLibrary1.Class1类型的对象(与上面的不同),结果在编译器错误中

我建议您遵循我在下面链接的教程,因为恕我直言,这是实现面向服务架构的正确方法。单独保留服务引用 - 它最终会重复代码。

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

  1. 创建合同项目并移动接口 (IService1) 和 DTO(您的 Response class 是一个 DTO,而您正在 returning Class1,这也是一个 DTO) 到这个项目。
  2. 包含实施的服务项目 (Service1) 应参考您的合同 class
  3. 控制台应用程序应引用您的合同项目
  4. 更新您的服务参考

原创

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

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

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

此错误来自 ConsoleApplication1(客户端)引用 WcfServiceLibrary1(主机),导致在 [ConsoleApplication1 -> Service References -> ServiceReference1 -> [=23] 中自动生成服务代码=] -> Reference.cs] 重用 WcfServiceLibrary1.Response(它依赖于 ClassLibrary1.Class1,来自 CS0012),否则会创建 ServiceReference1.Class1 来处理 AltConvertToClass 方法。

解决方案是删除从 ConsoleApplication1(客户端)到 WcfServiceLibrary1(主机)的引用,这很有意义,因为这两个程序集通常 运行单独的机器。

感谢大家的贡献!