Повторное использование типов в текущей сборке для прокси WCF - PullRequest
10 голосов
/ 30 мая 2009

VS Интеграция с WCF имеет приятную опцию «Повторное использование типов в сборках с привязкой». Проблема в том, что мне нужно то же самое, но для текущей сборки. Некоторые типы уже определены в моей сборке, и мне нужно использовать их повторно.

Сценарий использования:

  1. У меня есть сборка, и здесь есть TypeA.
  2. Я добавляю ссылку на службу, и один из методов возвращает тип, полностью совместимый с TypeA (свойства, имя).
  3. При добавлении ссылки на службу создается прокси-сервер, но в нем создается новый TypeA.

На шаге 3 мне нужен прокси, который будет возвращать TypeA. Не новый TypeA.

Ответы [ 3 ]

12 голосов
/ 31 мая 2009

Если я понимаю, что вы хотите сделать, то это сценарий, с которым я обычно сталкиваюсь, и у WCF есть достойный ответ: просто не используйте мастера ссылок на службы SvcUtil / WS.

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

Нет ничего, что заставляет вас использовать svcutil и друзей, просто определите свой интерфейс и либо напрямую используйте модель канала (например, ChannelFactory и друзья), либо, если вы предпочитаете использовать прокси-классы, просто создайте свою собственную ClientBase * Класс 1006 *. Это действительно очень просто и избавит вас от неприятностей в долгосрочной перспективе.

6 голосов
/ 19 августа 2010

Существует простой способ обмена типами между клиентом и службой, просто добавив ссылку на сборку общего типа на ваш клиент ПЕРЕД добавлением ссылки на службу.

Подробный сценарий и пример проекта можно найти там:

http://blog.walteralmeida.com/2010/08/wcf-tips-and-tricks-share-types-between-server-and-client.html

0 голосов
/ 06 февраля 2013

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

Что нужно сделать:

  1. Используйте svcutil с / t: метаданными для каждого URL.
  2. Переименуйте все созданные файлы с помощью чего-то уникального для службы (например, переименуйте lala.xsd в 1_lala.xsd)
  3. Копирование всех сгенерированных файлов в одно место
  4. Используйте svcutil с * .xsd .wsdl /out:output.cs / namespace: , MySpecialNamespace для генерации ВСЕХ контрактов на обслуживание и контрактов данных в один файл.

Если вы хотите быть хитрым: используйте следующий шаблон T4:

<#@ template language="C#v4.0" hostspecific="True"#>
<#@ import namespace="System.Diagnostics" #>
<#@ import namespace="System.IO" #>
<#=GetGeneratedCode(
"http://localhost/Service/Service1.svc",
"http://localhost/Service/Service2.svc",
"http://localhost/Service/Service3.svc",
"http://localhost/Service/Service4.svc"
)#>
<#+
const string _svcutil = @"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\svcutil.exe";

private string GetGeneratedCode(params string[] urls)
{
    var tmp = GetTemporaryDirectory();
    foreach (var url in urls)
    {
        GetMetadata(url, tmp);
    }

    RunSvcutil(tmp, "*.wsdl *.xsd /out:output.cs /namespace:*," +     Path.GetFileNameWithoutExtension(Host.TemplateFile));
    var result = File.ReadAllText(Path.Combine(tmp, "output.cs"));
    return result;
}

private static void RunSvcutil(string workingFolder, string arguments)
{
    var processInfo = new ProcessStartInfo(_svcutil);
    processInfo.Arguments = arguments;
    processInfo.WorkingDirectory = workingFolder;

    var p = Process.Start(processInfo);
    p.WaitForExit();
}

private static void GetMetadata(string url, string destination)
{
    var workingFolder = GetTemporaryDirectory();
    RunSvcutil(workingFolder, string.Format("/t:metadata \"{0}\"", url));

    foreach (var filename in Directory.GetFiles(workingFolder))
    {
        File.Copy(filename, Path.Combine(destination,     Path.GetFileNameWithoutExtension(url) + "_" +  Path.GetFileName(filename)));
    }
}

private static string GetTemporaryDirectory()
{
    string tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
    Directory.CreateDirectory(tempDirectory);
    return tempDirectory;
}
#>   
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...