我有一个客户端和服务器共享类型的应用程序,互操作性不是我们关注的问题之一。我计划为所有支持Web的对象提供一个存储库,我正在考虑为我的公开服务提供通用接口。
类似T GetObject(int id)
但是wcf不喜欢它,因为它试图暴露它的架构(我真的不关心)
是否可以使用WCF做这样的事情?,我可以使用任何类型的绑定不必是httpbinding或wsbinding ...
答案 0 :(得分:8)
客户端向服务器发送消息并获取响应。该消息是客户端和服务器之间传递的所有消息,需要可序列化为XML或二进制格式。这就是为什么传递的任何数据必须是原子的(如int,string)或DataContract - WCF服务堆栈的描述,关于如何序列化和反序列化这些对象。
你不能传递任何接口或其他“技巧” - 客户端和服务器之间的所有内容必须在XML模式中表达,基本上。
所以我担心你想要达到的目标与WCF提供的完全相反。 SOA(面向服务的应用程序)的世界和范例是完全不同的,并不总是100%与OOP的想法和机制同步。
马克
答案 1 :(得分:2)
我想这是可能的,虽然我不确定你是否想要这个。我采取以下方法(未经测试,不确定它是否有效)。首先在解决方案中创建以下项目结构:
ServiceInterfaces
ServiceImplementations
(参考ServiceInterfaces
和ModelClasses
)ModelClasses
Host
(参考ServiceInterfaces
和ServiceImplementations
)Client
(参考ServiceInterfaces
和ModelClasses
)在ServiceInterfaces
中,你有一个这样的界面(我跳过命名空间等,以缩短示例):
[ServiceContract]
public interface IMyService<T>
{
T GetObject(int id);
}
在ServiceImplementations
中,您有一个实现IMyService<T>
的类:
public class MyService<T> : IMyService<T>
{
T GetObject(int id)
{
// Create something of type T and return it. Rather difficult
// since you only know the type at runtime.
}
}
在Host
中,您可以在App.config
(或Web.config
)文件中使用正确的服务配置,并使用以下代码来托管您的服务(因为它是独立的应用):
ServiceHost host = new ServiceHost(typeof(MessageManager.MessageManagerService))
host.Open();
最后在Client
中,您使用ChannelFactory<TChannel>
类来定义代理:
Binding binding = new BasicHttpBinding(); // For the example, could be another binding.
EndpointAddress address = new EndpointAddress("http://localhost:8000/......");
IMyService<string> myService =
ChannelFactory<IMyService<string>>.CreateChannel(binding, address);
string myObject = myService.GetObject(42);
同样,我不确定这是否有效。诀窍是在主机和客户端之间共享服务接口(在ServiceInterfaces
)和域模型对象(在ModelClasses
中)。在我的示例中,我使用字符串从服务方法返回,但它可以是ModelClasses
项目中的任何数据协定类型。
答案 2 :(得分:0)
如果您使用ServiceKnownTypesDiscovery,则可以这样做。
例如:
[ServiceKnownType("GetKnownTypes", typeof(ServiceKnownTypesDiscovery))]
public interface ISomeService
{
[OperationContract]
object Request(IRequestBase parameters);
}
其中GetKnownTypes可以这样声明:
public static class ServiceKnownTypesDiscovery
{
public static IEnumerable<Type> GetKnownTypes(ICustomAttributeProvider provider)
{
var types = new List<Type>();
foreach (var asmFile in Directory.GetFiles(AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory, "*.dll"))
{
Assembly asm = Assembly.LoadFrom(asmFile);
types.AddRange(asm.GetTypes().Where(p=> Attribute.IsDefined(p,typeof(DataContractAttribute))));
}
return types;
}
}
在这种情况下,使用[DataContract]声明的所有内容(只要它们在服务器和客户端都可以发现)都可以序列化。
我希望这有帮助!
答案 3 :(得分:0)
按照上一个示例,您可以声明DataContract
,其对象为DataMember
。然后,您可以添加扩展方法以在对象数据成员上获取和设置泛型类型。您也可以将其设为内部,这样您就不得不使用扩展方法来获取和设置值。
当然,只有在使用svcutil
(或Visual Studio)生成客户端并且引用包含数据协定的程序集和带扩展方法的类时,它才有效。
希望这会有所帮助......