Универсальная программа для доступа к сервису WCF от клиента - PullRequest
2 голосов
/ 11 января 2012

Пожалуйста, посмотрите на код ниже, где клиент получает доступ к услуге WCF

Функция GetPriority

public List<Priority> GetPriority()
        {
            List<Priority> lstPriority = new List<Priority>();

            using (TmsServiceClient client = new TmsServiceClient())
            {
                try
                {
                    lstPriority =  client.GetPriority();
                }
                catch (FaultException<TMSCustomException> myFault)
                {
                    Console.WriteLine(myFault.Detail.ExceptionMessage);
                    client.Abort();
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    client.Abort();                  
                }
            }
            return lstPriority;
        }

Функция GetStatus:

public List<Status> GetStatus()
    {
        List<Status> lstStatus = new List<Status>();
        using (TmsServiceClient client = new TmsServiceClient())
        {
            try
            {
                lstStatus =  client.GetStatus();
            }
            catch (FaultException<TMSCustomException> myFault)
            {
                Console.WriteLine(myFault.Detail.ExceptionMessage);
                client.Abort();                   
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                client.Abort();                   
            }
        }

        return lstStatus;
    }

Оба метода работают нормально. Как можно видеть, существует много сходства между этими двумя методами, и они различаются только во время вызова метода и возвращаемого типа. Может ли это быть общим? Если так, то как это сделать? Или любым другим лучшим способом, чтобы код блока исключений catch не повторялся каждый раз.

Заранее спасибо

1 Ответ

2 голосов
/ 11 января 2012

Вы можете легко преобразовать почти весь метод Get ... в общий. Единственная реальная переменная часть - это какой клиентский метод вызывать, что можно легко решить с помощью Func<T,TResult>.

private List<T> Get<T>(Func<TmsServiceClient, List<T>> clientCall)
{
    List<T> results = new List<T>();
    using (TmsServiceClient client = new TmsServiceClient())
    {
        try
        {
            // invoke client method passed as method parameter
            results = clientCall(client);
        }
        catch (FaultException<TMSCustomException> myFault)
        {
            Console.WriteLine(myFault.Detail.ExceptionMessage);
            client.Abort();                   
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            client.Abort();                   
        }
    }

    return results;
}

Теперь ваши реализации методов выглядят так:

public List<Status> GetStatus()
{
    return Get<Status>(client => client.GetStatus());
}

public List<Priority> GetPriority()
{
    return Get<Priority>(client => client.GetPriority());
}

Редактировать в ответ на комментарий OP :

Func<TmsServiceClient, List<T>>, переданный в качестве параметра в Get<T> метод - это делегат . Делегат - это своего рода указатель на функцию - объект, который вы используете для делегирования некоторых действий, которые будут выполнены позже (отсюда и название).

Func<TmsServiceClient, List<T>> - это в основном делегат, который принимает один входной аргумент (типа TmsServiceClient) и возвращает List<T> в результате.

Теперь, что мы делаем, например, GetStatus? Мы создаем экземпляр такого делегата (через лямбда-выражение ) - и «приказываем» ему выполнить GetStatus() метод для Client объекта, который мы предоставим :

    // this line works the same as in example above
    //                  Take client as parameter    call its .GetStatus method
    return Get<Status>((TmsServiceClient client) => client.GetStatus());

И это именно то, что происходит в

    // invoke client method passed as method parameter
    results = clientCall(client);

линия. Делегат выполняет метод, который мы просили.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...