我已经开始使用this project来尝试学习CQRS并编写可维护的WCF服务。但是,我对WCF有一些一般性问题。每次添加命令/查询处理程序契约和处理程序时,我都会构建项目,然后在Visual Studio中右键单击客户端上的服务引用,并选择“更新服务引用”。这通常允许我使用新命令/查询而没有任何问题。
然而,比我想要的更频繁,我必须删除整个服务引用然后再添加它。这是我能解决这个错误的唯一方法:
尝试序列化参数时出错 http://tempuri.org/:query。 InnerException消息是'Type 'Contract.Queries.Countries.GetCountriesStartingWithLetterQuery'用 数据合同名称 'GetCountriesStartingWithLetterQuery:http://schemas.datacontract.org/2004/07/Contract.Queries.Countries' 不是预期的。考虑使用DataContractResolver或添加任何 静态地知道已知类型列表的类型 - 例如, 通过使用KnownTypeAttribute属性或将它们添加到 传递给DataContractSerializer的已知类型列表。'。请参阅 InnerException以获取更多详细信息。
然后有时候,即使我删除了服务引用并重新添加它,我也永远不会让新的命令/查询工作。如果我尝试在已注册已知类型的WCF服务代码中添加断点,它永远不会被命中。似乎服务引用失败,因为新命令/查询未注册为已知类型。
在此CQRS WCF模型中刷新服务的正确方法是什么?感谢。
更新1:我的所有麻烦来自EF生成代理对象并尝试通过WCF服务发送它们。该服务不了解代理,只知道POCO。
@Peter - 我正在使用EF 5 Code First。我将所有POCO都放在一个单独的项目中。我使用存储库模式从数据库中检索实体。当我说countryRepository.GetById(myId)时,会检索代理对象,而不是POCO。如果我禁用ProxyCreation,则会返回POCO,但导航属性始终为null,同时填充其各自的外键ID。也许我只需要在从存储库中获取内容时使用.Include作为导航属性?我明天要检查,因为我现在无法访问代码。
或者,我已经阅读了很多关于AutoMapper的内容。可以用来将我的代理对象映射到POCO吗?只是一个想法,但这似乎不正确。
编辑2:结果我可以使用ValueInjector将我的动态代理对象非常容易地映射到POCO。然后,我可以通过电线发送POCO,没有任何问题。 See this post以供进一步参考。
答案 0 :(得分:3)
不要使用添加服务引用。您可以使用频道工厂而不使用服务参考。这假设您可以通过添加项目(或dll)引用与客户共享您的数据和服务合同。
添加对客户端的引用。然后建立一个渠道工厂。这是来自MSD How to: Use the ChannelFactory
的简单文章如果您无法分享您的参考资料,可以查看如何从Carlos Figueira实施通用合约解析器WCF Extensibility – Data Contract Resolver。
编辑1:
您可以使用POCO pattern with EF获取导航属性,并与EF细节离婚。
答案 1 :(得分:0)
您不应该通过电汇发送实体。创建特定于服务方法的DTO /消息对象,并将它们映射到服务内部的实体。
答案 2 :(得分:0)
问题可能是由Visual Studio的编辑和继续功能引起的。 Visual Studio使用您的WCF服务旋转IIS Express或Cassini实例,并且在第一次访问时,WCF服务初始化(这是创建容器时以及调用GetKnownTypes
方法时)。
但是在添加新类型和重新编译时,Visual Studio会更改WCF服务的程序集,但不会重新启动该AppDomain,从而保持Web服务的初始化(因为初始化只发生一次)但配置无效。
您可以通过在每次开始调试时终止IIS Express实例来解决此问题,但当然这非常烦人。也许你可以自动化这个,但至少问题永远不会存在于生产中,因为没有编辑和继续。
现在我通常不会将我的命令和查询作为WCF合同的一部分公开。客户端和服务器现在只是前后发送JSON对象,而WCF服务涉及的只是一个字符串。事实证明,通过线路发送JSON对我非常有益,因为: