在DataContract中访问WCF服务设置访问器?

时间:2011-04-27 04:57:25

标签: wcf datacontract

天儿真好,

我试图弄清楚如何(如果可能的话)从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请求时,这似乎是浪费。

任何帮助都会受到赞赏。如有任何问题或需要更多信息,请随时提出。

非常感谢, 史蒂夫

2 个答案:

答案 0 :(得分:3)

我有类似的问题。当客户端访问某些属性时,我需要此功能来执行一种“延迟”加载。 当您的服务客户端使用ChannelFactory(来自WCF)时,您必须具有对定义SerivceContracts和OperationContracts的程序集的引用。 然后,您可以轻松实现在同一程序集中创建serivce通道的方法。

在SerivceContract / 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);

答案 1 :(得分:1)

虽然我首先不同意这样做,但探索这个想法很有意思。

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

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

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

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

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

您可以检查 OperationContext.Current 是否为null。或者您可以手动编写服务器端和客户端接口定义,以便服务器的 MyType 实现具有此额外的setter逻辑,而客户端的实现则没有。当然,有两个相应但略有不同的接口定义会引入整个维护问题。

祝你好运,我对你的冒险经历如何运作感兴趣。