2014-11-17 8 views
7

Во-первых, это не дубликат IEnumerable<T> as return type for WCF methods, я думаю, я понимаю, что архитектура WCF позволяет передавать только конкретные типы, которые могут быть добавлены в сообщение.Получение IEnumerable <T> семантики с помощью службы WCF NetTcpBinding?

Во-вторых, наша установка, однако, не общего обслуживания, но подключение до сверток фирменных приложений с помощью C# + WCF + NetTcpBinding + Protobuf (только), чтобы мы могли иметь больше возможностей для некоторых трюков, которые что-то, что нужно чтобы быть более нейтральной.

В-третьих, это не мое место и не этот вопрос, чтобы предложить другую структуру RPC или обмена сообщениями.


«IEnumerable семантика», для целей данного вопроса, являются:

  • Возвращенный последовательность может быть сколь угодно большой - поэтому не можно преобразовать последовательность к List или похожие.
  • Он не заранее известно, сколько элементов будет возвращено
  • Caller можно просто использовать foreach и сделать с ней.

В локальной сборки, A # интерфейс C мой выглядеть следующим образом:

interface IStuffProvider { 
    IEnumerable<Stuff> GetItems(); // may open large file or access database 
} 

Вы не можете отобразить, что непосредственно к службе WCF. То, что могло бы достичь того же может выглядеть следующим образом:

[ServiceContract(SessionMode = SessionMode.Required)] 
interface IStuffService { 
    [OperationContract] 
    void Reset(); // may open large file or access database 
    [OperationContract] 
    List<Stuff> GetNext(); // return next batch of items (empty list if no more available) 
} 

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

Одним из вариантов было бы, конечно, иметь реализацию оболочки интерфейса клиентской стороны, которая предоставляет IStuffProvider и внутренне перенаправляет и использует IStuffService. Однако, действительно, было бы желательно, чтобы не должны поддерживать два интерфейса, один для пользовательского кода, один исключительно для связи WCF, особенно, поскольку все эти приложения все тесно связаны друг с другом, поэтому дополнительная абстракция просто накладная.

Какие у нас есть варианты с WCF?


Обратите внимание, что после чтения на нем, то Streamed Binding кажется плохим решением, так как я бы еще нужна обертка на стороне клиента и сервисный интерфейс получит более сложным никакой реальной выгоды в моей case: Мне не нужна максимальная эффективность бинарного переноса, я бы хотел, чтобы хорошая реализация + эффективность обслуживания.

+5

может быть, вы можете использовать [Streaming функциональность] (http://msdn.microsoft.com/en-us/library/ms733742 (v = vs.110). aspx), что от WCF? (Я не использовал WCF какое-то время, поэтому, я не уверен, что это подходит ...) –

+0

@AasmundEldhuset - безусловно, стоит прочитать. Тем не менее, похоже, много ссылок. –

+0

WCF имеет тенденцию быть таким, не так ли? ;-) –

ответ

0

То, что я сделал в конце концов, есть:

а) OO интерфейсIStuffProvider как указано выше, с GetLines() элементом, как описано выше.

б) Интерфейс WCF службы (и его реализации) реализует модель доступа, как это:

[OperationContract] 
    ReadToken StartReadingLines(...); 

    [OperationContract] 
    // return next batch of items (empty list if no more available) 
    List<Stuff> ReadNextLines(ReadToken readToken); 

    [OperationContract] 
    void FinishReadingLines(ReadToken readToken); 

с) клиент получает доступ услугу через прокси-класса, который реализует IStuffProvider и отображает вызов GetLines() функция этих трех функций:

// implementation in the proxy class: 
    public IEnumerable<Stuff> GetLines() 
    { 
     var readToken = _dataService.StartReadingLines(...); 
     try { 
      for (List<Stuff> lines = _dataService.ReadNextLines(readToken); lines.Count > 0; lines = _dataService.ReadNextLines(readToken)) { 
       foreach (var line in lines) { 
        yield return line; 
       } 
      } 
     } finally { 
      _dataService.FinishReadingLines(readToken); 
     } 
    } 
1

Некоторое время назад мы столкнулись с тем же «ограничением» WCF в нашем проекте. Одним словом, мы закончили с

interface IStuffProvider { 
    List<Stuff> GetItems(int page, int pageSize); // may open large file or access database 
} 

Да, это не то же самое, как IEnumerable<Stuff> GetItems(); Да, мы можем получить в неприятности, когда какой-то предмет добавлять/удалять на уже полученную страницу. Да, требуются некоторые настройки на стороне сервера, если сервер работает с элементами в терминах IEnumerable<Stuff>. Но он все еще строго типизирован и не приносит много дополнительной логики на клиенте или на сервере.

+1

«Обратите внимание, что это не ответ на вопрос, а некоторые общие мысли». - Если это не будет опубликовано в качестве комментария, то? –

+0

@DarrenYoung no –

+1

Это не дает ответа на вопрос. Чтобы критиковать или просить разъяснения у автора, оставьте комментарий ниже их сообщения. –