1

Вопрос по wcf, c# – Библиотека служб WCF, размещенная как служба Windows с использованием Castle.Windsor 3.0

Я хочу разместить мою сервисную библиотеку WCF в службе Windows. Хотя он будет связываться с другим wcfservice по локальной сети.

Я испытываю большие трудности с поиском последней, актуальной документации или помощью в настройке решения для этой цели. Может кто-нибудь посоветовать:

а) Какая предпочтительная конечная точка для такого рода соединения? (Другая служба WCF размещается с использованием basicHttpBinding) - это само по себе хорошо подходит для настройки контейнера Castle путем перехвата global.asax. Тем не менее, размещение этого решения в службе Windows означает, что у меня больше нет доступа к global.asax!

б) Как настроить Castle Windsor для использования DI с этим решением? В настоящее время я изучил возможность подключения к методу AppInitilize () App_Code и некоторых других, более недействительных решений.

Архитектура текущего решения:

* Core (библиотека классов C #)

* Услуги (библиотека классов C #)

* WCF Servics (Сервисная библиотека WCF)

* Служба Windows (Windows Service Project)

Пример кода для AppInitilize () [который в настоящее время, похоже, не работает]:

public class WindsorConfiguration
    {
        public static IWindsorContainer Container { get; private set; }

        public static void AppInitialize()
        {
            {
                Container = new WindsorContainer()
                    .AddFacility<WcfFacility>()
                    .Register(Component.For<IVirusCheckService>().ImplementedBy<VirusCheckService>()
                                  .LifeStyle.Transient
                                  .AsWcfService(new DefaultServiceModel()
                                                    .AddBaseAddresses("http://localhost:8080/MyService")
                                                    .AddEndpoints(WcfEndpoint.BoundTo(new BasicHttpBinding())
                                                                      .At("basic"))
                                                    .PublishMetadata(o => o.EnableHttpGet())))
                    .Register(Component.For<ILoggingService>().ImplementedBy<LoggingService>());
            }
        }
  • Я не могу быть уверен, что вызвало бы это, без дополнительной информации. Возможно, вам следует создать новый вопрос со всеми соответствующими битами (например, установщик и т. Д.). Сначала я бы сказал, что сначала создайте сервис, который является обычным пустым сервисом, и убедитесь, что он устанавливается и работает нормально (поэтому в нем нет логики), а затем добавьте часть замка, которая регистрирует ServiceBase, и убедитесь, что работает, а затем добавить в биты WCF и убедитесь, что работает. Затем у вас будут ингредиенты для хорошего вопроса (просто прекратите, когда он не работает), или он просто работает, и вы решили его.

    от
  • Наконец, приступив к реализации этого решения, я столкнулся с проблемой. При запуске службы я получаю «ошибку 1083», исполняемая программа, для которой настроена эта служба, не реализовала службу ». Насколько мне известно, это относится либо к: именам служб, не совпадающим с установщиками, либо к исполняемому файлу, полученному из базы служб, не зарегистрирован? Любые предложения здесь?

    от M05Pr1mty
  • Отличный ответ, спасибо.

    от M05Pr1mty
  • Где находится ServiceHost в этом примере?

    от
  • В самом деле? Никто не получил никаких предложений по этому вопросу ?! Конечно, это не так туманно?

    от M05Pr1mty
  • 3

    Ответить на вопрос

    a (вроде) - я не думаю, что есть "предпочтительный" подход - это действительно зависит от того, как вы хотите, чтобы ваши услуги были доступны. Я размещал net.tcp (я подозреваю, что он наиболее распространен в среде службы Windows, но я предполагаю), службы webhttp, basichttp и wshttp прекрасно работают внутри службы Windows. Наb...

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

    После того, как контейнер загружен, я определяю ServiceBase из контейнера и передаю егоServiceBase.Run статический метод. Таким образом, мой сервис может зависеть от того, что еще зарегистрировано в контейнере (это единственное место, которое я бы назвал Resolve для контейнера, но я думаю, что это оправдано в этом случае).

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

    static class Program
    {
        static void Main()
        {
            ServiceBase.Run(CreateContainer().Resolve<ServiceBase>());
        }
    
        private static IWindsorContainer CreateContainer()
        {
            var container = new WindsorContainer();
            container.Install(FromAssembly.This());
            return container;
        }
    }
    
    public class ServicesInstaller : IWindsorInstaller
    {
        public void Install(IWindsorContainer container, IConfigurationStore store)
        {
            container
                .AddFacility<WcfFacility>(f =>
                                              {
                                                  f.CloseTimeout = TimeSpan.Zero;
                                              })
                .Register(
                    Component
                        .For<IVirusCheckService>()
                        .ImplementedBy<VirusCheckService>()
                        .LifeStyle.Transient
                        .AsWcfService(new DefaultServiceModel()
                                          .AddBaseAddresses("http://localhost:8080/MyService")
                                          .AddEndpoints(WcfEndpoint.BoundTo(new BasicHttpBinding())
                                                            .At("basic"))
                                          .PublishMetadata(o => o.EnableHttpGet())),
                    Component
                        .For<ServiceBase>()
                        .ImplementedBy<MyService>());
        }
    }
    

    NOTE: The MyService class is just a regular Windows service class (you can use the one visual studio generates for you when you go file | new | windows service if you like) - I have not shown it because it can just be an empty implementation.