2015-05-11 2 views
0

Давайте предположим, что у меня есть следующие методы:Как реорганизовать «использование», чтобы избежать дублирования кода?

public string GetSchedules(string request) 
    { 
     using (var soapClient = new ServiceReference1.CustomDataTimetableToolKitServicesSoapClient(EndpointConfiguratioName, Endpoint)) 
     { 
      return soapClient.GetSchedules(AuthenticationInfo, request); 
     } 
    } 

    public string GetCountryList(string request) 
    { 
     using (var soapClient = new ServiceReference1.CustomDataTimetableToolKitServicesSoapClient(EndpointConfiguratioName, Endpoint)) 
     { 
      return soapClient.GetCountryList(AuthenticationInfo, request); 
     } 
    } 

    public string GetCarriers(string request) 
    { 
     using (var soapClient = new ServiceReference1.CustomDataTimetableToolKitServicesSoapClient(EndpointConfiguratioName, Endpoint)) 
     { 
      return soapClient.GetCarriers(AuthenticationInfo, request); 
     } 
    } 

Как вы можете видеть только другая вещь является имя метода вызывается. Как я могу реорганизовать эти методы, чтобы применять «использование» только один раз и избегать дублирования кода?

+0

Лучшие практики для * не * использовать 'using' заявление с клиентами WCF - [MSDN] (https://msdn.microsoft.com/en-us/library/aa355056 .aspx) – Tim

ответ

5

мне, что у вас есть это хорошо, но если вы хотите, чтобы учитывать те из вас могут использовать Func и лямбды. Что-то вдоль этих линий:

public string GetSchedules(string request) 
{ 
    return Worker((c) => c.GetSchedules(AuthenticationInfo, request)); 
} 

public string GetCountryList(string request) 
{ 
    return Worker((c) => c.GetCountryList(AuthenticationInfo, request)); 
} 

public string GetCarriers(string request) 
{ 
    return Worker((c) => c.GetCarriers(AuthenticationInfo, request)); 
} 

private string Worker(Func<SoapClientClassGoesHere, string> f) 
{ 
    using (var soapClient = new ServiceReference1.CustomDataTimetableToolKitServicesSoapClient(EndpointConfiguratioName, Endpoint)) 
    { 
     return f(soapClient); 
    } 
} 

Func<A, R> означает «функция, которая принимает аргумент типа A и возвращает значение типа R» (и вы можете иметь Func<A, B, R> для функции, которая принимает два аргументов и т.д.).

Подробнее о Func<> и lambdas в this question и this question (и многое другое, это богатая тема).

Вот live example on ideone.com (очень глупый живой пример, но он демонстрирует концепцию):

using System; 
using System.Collections.Generic; 

class Foo { 
    public string GetSchedules(string request) 
    { 
     return Worker((c) => c[request]); 
    } 

    public string GetCountryList(string request) 
    { 
     return Worker((c) => c[request].ToUpper()); 
    } 

    public string GetCarriers(string request) 
    { 
     return Worker((c) => c[request].ToLower()); 
    } 

    private string Worker(Func<Dictionary<string,string>, string> f) 
    { 
     var d = new Dictionary<string, string>(); 
     d.Add("1", "One"); 
     d.Add("2", "Two"); 
     d.Add("3", "Three"); 
     return f(d); 
    } 
} 

public class Test 
{ 
    public static void Main() 
    { 
     var f = new Foo(); 
     Console.WriteLine(f.GetSchedules("1")); 
     Console.WriteLine(f.GetCountryList("1")); 
     Console.WriteLine(f.GetCarriers("1")); 
    } 
} 
+0

Вам необходимо передать 'запрос' делегату, поэтому вам нужно передать его' Worker', и вам нужно будет обновить подпись 'Func'. –

+0

@JohnSaunders: Нет, вы этого не сделали, лямбда закрывается над ним: http://ideone.com/pjxEio –

+0

спасибо за разъяснения –

2

Там действительно не так много дублирования. Тем не менее,

public ServiceReference1.CustomDataTimetableToolKitServicesSoapClient NewClient() 
{ 
    return new ServiceReference1.CustomDataTimetableToolKitServicesSoapClient(EndpointConfiguratioName, Endpoint) 
} 

using (var client = NewClient()) { 
    return soapClient.GetCountryList(AuthenticationInfo, request); 
} 

Кроме того, поскольку все ваши методы принимают параметр string и вернуть string, было бы легко написать один метод для вызова их всех, проходя операцию для вызова в качестве делегата. К сожалению, у меня нет времени написать это для вас прямо сейчас.

+0

Я не вижу, как это помогает - на самом деле, если что-то добавляет метод? Обратите внимание, что каждый вызов относится к другой конечной точке – JamesSugrue

+0

спасибо за ваш ответ @Jhon Saunders –

+0

@JamesSugrue: он централизует создание экземпляра прокси. Однако он должен быть создан, он будет создан только в одном месте. –

2

Вы можете использовать функцию лямбда таким образом:

public string GetCarriers(string request) 
{ 
    return Get((authInfo, request) => soapClient.GetCarriers(authInfo, request), request); 
} 

... 

public string Get(Func<AuthenticationInfo, string, string> action, string request) { 
    using (var soapClient = new ServiceReference1.CustomDataTimetableToolKitServicesSoapClient(EndpointConfiguratioName, Endpoint)) 
    { 
     return action(AuthenticationInfo, request) 
    } 
} 

Я не знаю, если это компилируется, но вы получите идею.

Edit: Как заметил С. @ Тим, этот код, вероятно, может быть короче:

public string GetCarriers(string request) 
{ 
    return Get(soapClient.GetCarriers, request); 
} 

... 

public string Get(Func<AuthenticationInfo, string, string> action, string request) { 
    using (var soapClient = new ServiceReference1.CustomDataTimetableToolKitServicesSoapClient(EndpointConfiguratioName, Endpoint)) 
    { 
     return action(AuthenticationInfo, request) 
    } 
} 

Edit 2: Клиент был из области видимости. Так правильный код:

public string GetCarriers(string request) 
{ 
    return Get((client, authInfo, request) => client.GetCarriers(authInfo, request)); 
} 

... 

public string Get(Func<ISoapClient, AuthenticationInfo, string, string> action, string request) { 
    using (var soapClient = new ServiceReference1.CustomDataTimetableToolKitServicesSoapClient(EndpointConfiguratioName, Endpoint)) 
    { 
     return action(soapClient, AuthenticationInfo, request) 
    } 
} 
+0

Обнаружение ада найдено –

+0

@ Сергий Березовский: почему это проблема обслуживания? –

+0

@ Чтение и понимание @JohnSaunders является частью обслуживания –

0

Если Projekt не очень большой, вы можете использовать следующие (это немного грязный и делает его легким сделать ошибку):

public string getX (string request, string x) 
{ 
    using (var soapClient = new ServiceReference1.CustomDataTimetableToolKitServicesSoapClient(EndpointConfiguratioName, Endpoint)) 
    { 
     switch (x) 
     { 
      case "schedules": 
       return soapClient.GetSchedules(AuthenticationInfo, request); 
       break; 
      case "countryList": 
       return soapClient.GetCountryList(AuthenticationInfo, request); 
       break; 
      case "carriers": 
       return soapClient.GetCarriers(AuthenticationInfo, request); 
       break; 
      } 
     } 
    } 
} 
Смежные вопросы