Изменить существующий объект связи WCF - PullRequest
0 голосов
/ 29 марта 2012

Вот как я делал вызовы методов:

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 ]

1 голос
/ 30 марта 2012

Во-первых, вы не хотите создавать новый ChannelFactory<T> при каждом вызове вспомогательного метода Using. Это самая дорогая вещь для создания во вселенной 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();
        }
    }
} 
1 голос
/ 29 марта 2012

Это должно работать:

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);
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...