Существует ли таблица маршрутизации в стиле ASP для привязок NetTcp в IIS 7? - PullRequest
1 голос
/ 04 мая 2011

Я работаю над изменением привязок службы с Restful http на netTcp для набора служб приложений, размещенных на IIS 7. В конфигурации restful используется таблица маршрутизации, и динамически создаются конечные точки на основе соглашения об именахи внедрение зависимости.Поскольку теперь нам нужно вызывать их в блоке транзакций (DTS), мы конвертируем эти сервисы в привязки Net Tcp.

Я бы хотел иметь возможность сохранять маршрутизацию по используемой модели соглашения и внедрению зависимостей, а не иметь много грязных файлов .svc.Я знаю, что таблицы маршрутизации ASP не работают с другими привязками.Есть предложения по альтернативе?Может ли пользовательский HttpModule сделать это?

  • Будет голосовать за любую полезную информацию или пометит ответ или ссылку на ответ.

Спасибо, Аарон

Ответы [ 2 ]

4 голосов
/ 07 мая 2011

Нет, прямой привязки таблицы маршрутизации ASP.NET для привязок net.tcp не существует.И пользовательский модуль HttpModule не поможет, поскольку он предназначен только для HTTP;)

Однако, есть некоторые вещи, которые вы можете сделать.Прежде всего, если вы не хотите иметь файл .SVC для каждой из ваших служб, вы можете использовать активацию новой службы (WCF 4) на основе конфигурации, которая позволяет объявлять все службы WCF в приложении Web.config.(внутри system.serviceModel), например:

<serviceHostingEnvironment>
  <serviceActivations>
    <add relativeAddress="Service1.svc" service="MyNamespace.MyService1"/>
    <add relativeAddress="Foo/Service2.svc" service="MyNamespace.MyService2"/>
    <add relativeAddress="Bar/a/Service3.svc" service="MyNamespace.MyService3" factory="System.ServiceModel.Activation.ServiceHostFactory"/>
  </serviceActivations>
</serviceHostingEnvironment>

Примечания:

  • Атрибут @factory по умолчанию равен ServiceHostFactory, т. е. его нужно указывать только в том случае, если выВы используете другой тип фабрики (например, WebServiceHostFactory или пользовательский)
  • Основной недостаток: @relativeAddress ДОЛЖЕН содержать расширение !!
  • Расширение должно быть объявлено в system.web/ compilation / buildProviders, и указанный там тип должен иметь атрибут [ServiceActivationBuildProvider] (System.ServiceModel.Activation)
  • Что означает, что в действительности вы в конечном итоге будете использовать расширение .svc, поскольку этоуже объявлен по умолчанию в корне. Web.config -

Но этот подход, по крайней мере, позволяет вам определять все ваши сервисы в одном месте.(в отличие от нескольких .svc файлов ) - и в этом отношении он сопоставим с RouteTable.

Теперь, если вас беспокоят расширения .svc, вы можете даже пойтина шаг впереди.Другим новым элементом в WCF4 является Служба маршрутизации (см. http://msdn.microsoft.com/en-us/library/ee517423.aspx), которая является универсальной службой WCF, которая принимает сообщения для пересылки их другим службам WCF на основе различных критериев (таких как заголовки SOAP,содержимое сообщения, адрес конечной точки и т. д.).

Используя службу маршрутизации, вы можете определить различные фильтры EndpointAddress (например, net.tcp: // {routing-service-base} / service1, net.tcp:// {routing-service-base} / service2 и т. д.), что еще больше приближает вас к маршрутизации ASP.NET.

Однако, если вы сами размещаете службу маршрутизации в IIS, очевидно, этабудет по-прежнему иметь .SVC базовый адрес!

Единственный способ обойти это последнее ограничение (т. е. как разместить саму службу маршрутизации на симпатичном URI, таком как net.tcp: // имя_сервера / XYZServices ) будет состоять в том, чтобы самостоятельно размещать только службу маршрутизации, например, в службе Windows, что дает вам полный контроль над ее базовым адресом. Затем вы можете продолжать размещать фактическую цельслужбы в IIS - с расширениями .svc - и ваша служба маршрутизации преобразует «хорошие» публичные URI в IIS .svc.

Однако трудно отказаться от хостинга IIS / AppFabric только дляполучить хорошие URI.Я, вероятно, не стал бы это делать.

Надеюсь, вы сможете использовать хотя бы часть этого:)

2 голосов
/ 06 июня 2012

Этому вопросу с его ответом почти год. Тем не менее, я столкнулся с той же проблемой.

Краткий ответ - это то, что вы уже обнаружили. Не работает Все же это никогда не останавливало нас. Некоторое исследование позже и небольшое «погружение» в механизм активации дало следующее рабочее решение:

public class CustomRouting
{
    public static void Route(string routePrefix, ServiceHostFactoryBase serviceHostFactory, Type serviceType)
    {
        var serviceHostingEnvironment = new StaticReflectionWrapper(typeof (ServiceHostingEnvironment));
        serviceHostingEnvironment.StaticMethod("EnsureInitialized");
        var hostManager = serviceHostingEnvironment.GetStaticField("hostingManager");

        var hostingManager = new InstanceReflectionWrapper(hostManager);
        var normalizedAddress = hostingManager.Method<string>("NormalizedRelativeAddress", routePrefix);
        var serviceActivation = new KeyValuePair<string, string>(normalizedAddress, string.Format("{0}|{1}|{2}", normalizedAddress, serviceHostFactory.GetType().FullName, serviceType.FullName));
        hostingManager.GetField<Hashtable>("serviceActivations").Add(serviceActivation.Key, serviceActivation.Value);

        var tD = StaticReflectionWrapper.Resolve(typeof (ServiceHostingEnvironment).Assembly, "TD");
        if (tD.StaticMethod<bool>("CBAEntryReadIsEnabled"))
        {
            tD.StaticMethod("CBAEntryRead", routePrefix, serviceActivation.Key);
        }

        ServiceHostingEnvironment.EnsureServiceAvailable(serviceActivation.Key);
    }
}

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

Вы используете метод Route следующим образом:

var fact = new CustomServiceHostFactory();
CustomRouting.Route("DynamicServices/" + service.GetType().Name + ".svc", fact, service.GetType());

Сервисная переменная является реализацией ServiceContract.

Используйте это на свой страх и риск, потому что это действительно низко в регионах, куда мы не должны приходить. Тем не менее, это работает.

Надеюсь, это сокращает время поиска для многих людей и открывает закрытые двери.

...