修改现有的WCF通信对象

时间:2012-03-29 05:50:35

标签: c# asp.net wcf entity-framework

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

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();
}

希望这是有意义的,并提前感谢。

2 个答案:

答案 0 :(得分:1)

这应该有效:

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);
        }
    }
}

答案 1 :(得分:1)

首先,您不希望每次调用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();
        }
    }
}