访问DataContract集访问器内的WCF服务



G'day,

我正试图弄清楚如何(如果可能的话(从datacontract属性的set访问器中访问WCF服务对象。

例如:

class MyService:IMyService
{
...
public string SomeMethod(int property)
...
}
[DataContract]
class MyType
{
[DataMember]
public int MyProperty
{
  ...
  set
  {
    // Use a call to the already created WCF instance inside the set accessor
    _otherValue = WCFInstance.SomeMethod(value);
  }
}
...
}

这可能不是最佳实践,但这可能吗?在上述情况下,我可以实例化MyService类的一个新实例来进行调用,但当内存中已经有一个实例在处理WCF请求时,这似乎是一种浪费。

如有任何协助,不胜感激。如有任何问题或需要更多信息,请随时询问。

非常感谢,Steve

我也遇到了类似的问题。我需要这个功能来在客户端访问某些属性时进行一种"懒惰"加载。当您的服务客户端使用ChannelFactory(来自WCF(时,您必须具有对定义SerialContracts和OperationContracts的程序集的引用。然后,您可以很容易地实现在同一程序集中创建serivce通道的方法。

在SerialContract/DataContract程序集中:

public class ServiceFactory
{
    private static Dictionary<Type, object> srvs = new Dictionary<Type, object>();
    private ServiceFactory()
    {
    }
    public static T GetService<T>(string configName = null)
    {
        if (!srvs.ContainsKey(typeof(T)))
        {
            if (String.IsNullOrEmpty(configName))
                throw new Exception("configName must be provided by client");
            srvs.Add(typeof(T), new ChannelFactory<T>(configName).CreateChannel());
        }
        return (T)srvs[typeof(T)];
    }
}
[DataContract]
public class Customer
{
    [DataMember]
    public int ID { get; set; }
    public Address Address
    {
        get 
        {
            return ServiceFactory.GetService<IMyService>().GetAddressByCustomerID(ID);
        }            
    }
}

客户端:

var srv = ServiceFactory.GetService<IMyService>("MyServiceEndpointConfigName");
// get a Customer DataContract object
var cust = srv.GetCustomerByID(1);
// calls automaticly the GetAddressByCustomerID method
var Console.WriteLine(cust.Address.City);

虽然我一开始就不同意这样做,但探索这个想法很有趣。

综合考虑:MyType的实例将在服务器端和客户端创建。它们要么由代码显式创建,要么在WCF框架反序列化消息时创建。例如,如果您的服务将MyType的对象作为参数,那么您的客户端代码将必须创建一个实例并将其传递给WCF调用。此时,WCF框架将通过调用所有getter方法并写入XML对其进行序列化,然后服务器端的WCF框架将创建一个新副本,并在反序列化期间调用所有集合方法。

在服务器端,您新反序列化的MyType实例可能能够通过以下代码获得服务实例:

var serviceInstance = (MyService) OperationContext.Current.InstanceContext.GetServiceInstance()

(我不知道这是否可行,因为在反序列化MyType实例时会调用set方法。当前InstanceContext此时可用吗?(

但在客户端,没有任何操作上下文,因此不能调用此代码。

您可以检查是否OperationContext。Current是否为null。或者,您可以手工编写服务器端和客户端接口定义的代码,这样服务器的MyType实现就有了这个额外的setter逻辑,而客户端的实现则没有。当然,有两个相对应但略有不同的接口定义会带来整个维护问题。

祝你好运,我会对你的冒险结果感兴趣的。

最新更新