修改现有WCF通信对象



这就是我过去进行方法调用的方式:

SvcHelper.Using<SomeWebServiceClient>(proxy =>
{
   proxy.SomeMethod();
}
public class SvcHelper
{
   public static void Using<TClient>(Action<TClient> action) where TClient : ICommunicationObject, IDisposable, new()
   {
   }
}

这就是我进行方法调用的方式:

ChannelFactory<ISomethingWebService> cnFactory = new ChannelFactory<ISomethingWebService>("SomethingWebService");
ISomethingWebService client = cnFactory.CreateChannel();
using (new OperationContextScope((IContextChannel)client))
{
   client.SomeMethod();
}

我的问题是:不是替换我原来方法调用方法的每个实例;有没有一种方法可以修改我的SvcHelper并在SvcHelper构造函数中创建通道,然后简单地传递如下接口:

SvcHelper.Using<ISomethingWebService>(client =>
{
   client.SomeMethod();
}

希望这是合理的,并提前感谢。

首先,您不希望每次调用Using-helper方法都创建一个新的ChannelFactory<T>。它们是WCF领域中构建成本最高的东西。因此,至少,您需要在那里使用缓存方法。

其次,你根本不想再把自己束缚在"客户"类型上。直接使用服务契约接口即可。

从你所拥有的开始,根据我过去的做法,我会去哪里:

public class SvcHelper
{
    private static ConcurrentDictionary<ChannelFactoryCacheKey, ChannelFactory> ChannelFactories = new ConcurrentDictionary<ChannelFactoryCacheKey, ChannelFactory>();
    public static void Using<TServiceContract>(Action<TServiceContract> action) where TServiceContract : class
    {
        SvcHelper.Using<TServiceContract>(action, "*");
    }
    public static void Using<TServiceContract>(Action<TServiceContract> action, string endpointConfigurationName) where TServiceContract : class
    {
        ChannelFactoryCacheKey cacheKey = new ChannelFactoryCacheKey(typeof(TServiceContract), endpointConfigurationName);
        ChannelFactory<TServiceContract> channelFactory = (ChannelFactory<TServiceContract>)SvcHelper.ChannelFactories.GetOrAdd(
                                                                                                                                cacheKey,
                                                                                                                                missingCacheKey => new ChannelFactory<TServiceContract>(missingCacheKey.EndpointConfigurationName));
        TServiceContract typedChannel = channelFactory.CreateChannel();
        IClientChannel clientChannel = (IClientChannel)typedChannel;
        try
        {
            using(new OperationContextScope((IContextChannel)typedChannel))
            {
                action(typedChannel);
            }
        }
        finally
        {
            try
            {
                clientChannel.Close();
            }
            catch
            {
                clientChannel.Abort();
            }
        }
    }
    private sealed class ChannelFactoryCacheKey : IEquatable<ChannelFactoryCacheKey>
    {
        public ChannelFactoryCacheKey(Type channelType, string endpointConfigurationName)
        {
            this.channelType = channelType;
            this.endpointConfigurationName = endpointConfigurationName;
        }
        private Type channelType;
        public Type ChannelType
        {
            get
            {
                return this.channelType;
            }
        }
        private string endpointConfigurationName;
        public string EndpointConfigurationName
        {
            get
            {
                return this.endpointConfigurationName;
            }
        }
        public bool Equals(ChannelFactoryCacheKey compareTo)
        {
            return object.ReferenceEquals(this, compareTo)
                       ||
                   (compareTo != null
                       &&
                   this.channelType == compareTo.channelType
                       &&
                   this.endpointConfigurationName == compareTo.endpointConfigurationName);
        }
        public override bool Equals(object compareTo)
        {
            return this.Equals(compareTo as ChannelFactoryCacheKey);
        }
        public override int GetHashCode()
        {
            return this.channelType.GetHashCode() ^ this.endpointConfigurationName.GetHashCode();
        }
    }
} 

这应该有效:

public class SvcHelper
{
    public static void Using<TClient>(Action<TClient> action) where TClient : ICommunicationObject, IDisposable
    {
        ChannelFactory<TClient> cnFactory = new ChannelFactory<TClient>("SomethingWebService");
        TClient client = cnFactory.CreateChannel();
        using (new OperationContextScope((IContextChannel)client))
        {
            action(client);
        }
    }
}

最新更新