Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
wcf公开泛型_Wcf_Generics_Wcf Binding - Fatal编程技术网

wcf公开泛型

wcf公开泛型,wcf,generics,wcf-binding,Wcf,Generics,Wcf Binding,我有一个客户端和服务器共享类型的应用程序,互操作性不是我们关心的问题之一。我计划为所有支持web的对象建立一个单一的存储库,并且我正在考虑为我公开的服务提供一个通用接口 类似于T GetObject(intid) 但是wcf不喜欢它,因为它试图公开它的模式(我并不真正关心) 有可能用WCF做这样的事情吗?我可以使用任何类型的绑定不必是httpbinding或wsbinding…不,你不能。无论您是否需要或需要互操作性,WCF的最基本的基础是消息交换。 客户端向服务器发送消息并返回响应。该消息是客

我有一个客户端和服务器共享类型的应用程序,互操作性不是我们关心的问题之一。我计划为所有支持web的对象建立一个单一的存储库,并且我正在考虑为我公开的服务提供一个通用接口

类似于T GetObject(intid)

但是wcf不喜欢它,因为它试图公开它的模式(我并不真正关心)


有可能用WCF做这样的事情吗?我可以使用任何类型的绑定不必是httpbinding或wsbinding…

不,你不能。无论您是否需要或需要互操作性,WCF的最基本的基础是消息交换。 客户端向服务器发送消息并返回响应。该消息是客户端和服务器之间传递的所有消息,需要序列化为XML或二进制格式。这就是为什么传递的任何数据都必须是原子的(如int、string)或DataContract,这是WCF服务堆栈关于如何序列化和反序列化此类对象的描述

您不能传递任何接口或其他“诡计”——客户端和服务器之间的所有内容基本上都必须能够在XML模式中表达

所以我担心你想要达到的目标与WCF提供的完全相反。SOA(面向服务的应用程序)的世界和范例是完全不同的,并不总是与OOP的思想和机制100%同步


马克

我想这是可能的,尽管我不确定你会想要这个。我会采用以下方法(未经测试,不确定是否有效)。首先在解决方案中创建以下项目结构:

  • ServiceInterfaces
  • 服务实现
    (参考
    服务接口
    模型类
  • ModelClasses
  • 主机
    (参考
    服务接口
    服务实现
  • 客户端
    (参考
    服务接口
    模型类
ServiceInterfaces
中,您有这样一个接口(我跳过了名称空间等,以缩短示例):

Host
中,您在
App.config
(或
Web.config
)文件中为您的服务提供了正确的配置,并使用以下代码托管您的服务(假设它是一个独立的应用程序):

最后,在
Client
中,您使用一个类来定义代理:

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);
Binding Binding=new BasicHttpBinding();//例如,可以是另一个绑定。
EndpointAddress地址=新的EndpointAddress(“http://localhost:8000/......");
IMyService myService=
CreateChannel(绑定,地址);
字符串myObject=myService.GetObject(42);

同样,我不确定这是否有效。诀窍是在主机和客户端之间共享服务接口(在
ServiceInterfaces
中)和域模型对象(在
ModelClasses
)。在我的示例中,我使用一个字符串从服务方法返回,但它可以是
ModelClasses
项目中的任何数据协定类型。

如果使用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;
    }
}
公共静态类ServiceKnownTypesDiscovery
{
公共静态IEnumerable GetKnownTypes(ICustomAttributeProvider提供程序)
{
变量类型=新列表();
foreach(目录.GetFiles(AppDomain.CurrentDomain.RelativeSearchPath??AppDomain.CurrentDomain.BaseDirectory,“*.dll”)中的var asmFile)
{
Assembly asm=Assembly.LoadFrom(asmFile);
types.AddRange(asm.GetTypes().Where(p=>Attribute.IsDefined(p,typeof(DataContractAttribute)));
}
返回类型;
}
}
在这种情况下,使用[DataContract]声明的所有内容(只要它们在服务器和客户端都可以发现)都可以序列化


我希望这有帮助

按照前面的示例,您可以声明一个对象为
DataMember
DataContract
。然后,您可以添加一个扩展方法来获取和设置对象数据成员的泛型类型。您也可以将其设置为内部,这样您就必须使用扩展方法来获取和设置值

当然,只有使用
svcuti
(或VisualStudio)生成客户机并使用extensions方法引用包含数据协定和类的程序集时,它才起作用


希望这有帮助……

所以如果有人想这样做,微软提供了什么技术堆栈,它更适合远程处理(如果它仍然存在的话)?Ms确实扩展了对共享类型(netcontractserializer等)的支持。我不知道目前是否有任何远程处理对象的解决方案—这基本上就是您正在尝试的。这种方法确实存在一些问题,微软试图用WCF来解决这些问题,但为了解决这些问题,我们必须使用完全基于消息的模型,这种模型在接口和泛型中不起作用。是的,它支持共享具体类型,但绝对不支持接口,也不支持真正的泛型。我可以在客户端引用相同的程序集,并使用服务引用UTILY(我猜是svcutil)的advance选项卡来共享类型,这是可行的,但现在我想做的是抽象的,我想我正在寻找remotint类型解决方案,但在wcf上应该是可能的…我的方法不应该使用Visual Studio中的“添加服务引用”对话框。那是行不通的。这就是我使用ChannelFactory类的原因。它会动态生成服务接口的代理实现,而不需要元数据。这很可能不起作用(我现在无法测试),因为您使用返回泛型类型“t”的操作定义服务,但为了正常工作,该类型“t”必须是DataContract,以便WCF堆栈可以序列化和反序列化该对象
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);
[ServiceKnownType("GetKnownTypes", typeof(ServiceKnownTypesDiscovery))]
public interface ISomeService
{
    [OperationContract]
    object Request(IRequestBase parameters);
}
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;
    }
}