Frage an c#, castle-windsor, windows-services, wcf – WCF-Dienstbibliothek, die als Windows-Dienst mit dem Castle.Windsor 3.0-Problem gehostet wird

1

Ich möchte meine WCF-Dienstbibliothek in einem Windows-Dienst hosten. Es wird zwar über ein lokales Netzwerk mit einem anderen wcf-Dienst kommuniziert.

Es fällt mir sehr schwer, eine aktuelle Dokumentation zu finden oder die Lösung für diesen Zweck zu konfigurieren. Kann mir jemand raten:

a) Was ist der bevorzugte Endpunkt für diese Art von Verbindung? (Der andere WCF-Dienst wird mit einem basicHttpBinding gehostet.) Dies eignet sich für sich genommen gut zum Konfigurieren des Castle-Containers durch Hijacking der global.asax. Durch das Hosten dieser Lösung in einem Windows-Dienst habe ich jedoch keinen Zugriff mehr auf ein global.asax!

b) Wie konfiguriere ich Castle Windsor für die Verwendung von DI mit dieser Lösung? Derzeit habe ich mich mit der AppInitilize () -Methode von App_Code und einigen anderen, nicht mehr gültigen Lösungen befasst.

Aktuelle Lösungsarchitektur:

* Core (C # -Klassenbibliothek)

* Dienste (C # -Klassenbibliothek)

* WCF Servics (WCF-Servicebibliothek)

* Windows-Dienst (Windows-Dienstprojekt)

Beispielcode für AppInitilize () [was derzeit nicht funktioniert]:

<code>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>());
            }
        }
</code>
"Ja wirklich?" Niemand hat Vorschläge dazu ?! Sicher ist es nicht so dunkel? M05Pr1mty

Deine Antwort

1   die antwort
3

Frage beantwortena (irgendwie) - Ich glaube nicht, dass es einen "bevorzugten" Ansatz gibt - es hängt wirklich nur davon ab, wie Sie möchten, dass Ihr Service verfügbar ist. Ich habe net.tcp gehostet (ich vermute, dass dies in einer Windows-Service-Umgebung am häufigsten vorkommt, aber ich vermute es). Auf zub...

Die Art und Weise, wie ich das mache (und vielleicht ist es nur ein Stil, aber es funktioniert für mich), ist, dass ich einen regulären Windows-Dienst habe und im Hauptprogramm den Container bootstrappe (also Dinge, die Sie in App_Start in global asax machen würden) ) und ich habe Installationsprogramme für die verschiedenen Teile der Anwendung, die ich installieren möchte (im Übrigen teile ich die Verträge in der Regel in WCF in ihre eigene Assembly auf und implementiere sie in der Windows-Service-Assembly oder in einer separaten Assembly, wenn ich sie hosten muss den gleichen Dienst an mehreren Orten).

Sobald der Container gebootet ist, löse ich die ServiceBase aus dem Container und gebe sie demServiceBase.Run statische Methode. Auf diese Weise kann mein Dienst Abhängigkeiten von allem haben, was im Container registriert ist (dies ist der einzige Ort, den ich jemals als Auflösen für den Container bezeichnen würde, aber ich denke, dass dies unter diesen Umständen gerechtfertigt ist).

Ich weiß nicht, was Sie von Ihrem Dienst anderes erwarten als das Hosten von WCF-Diensten, vielleicht nichts, aber dies ist ein gewisser Rahmen, der Sie zum Laufen bringt, also ist es hier ...

<code>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>());
    }
}
</code>

HINWEIS: Die MyService-Klasse ist nur eine reguläre Windows-Dienstklasse (Sie können den von Visual Studio generierten Dienst verwenden, wenn Sie zum Datei- | Neu- | Windows-Dienst wechseln). Ich habe ihn nicht angezeigt, da er nur eine leere Implementierung sein kann .

Wo ist der ServiceHost in diesem Beispiel? OutOFTouch
Tolle Antwort, danke. M05Pr1mty
Nachdem ich diese Lösung endlich implementiert habe, bin ich auf ein Problem gestoßen. Beim Starten des Dienstes erhalte ich den Fehler 1083, dass das ausführbare Programm, für dessen Ausführung dieser Dienst konfiguriert ist, den Dienst nicht implementiert. Soweit mir bekannt ist, bezieht sich dies entweder auf: Dienstnamen, die nicht mit den Installationsprogrammen übereinstimmen, oder die ausführbare Datei, die von der Dienstbasis stammt, ist nicht registriert? Irgendwelche Vorschläge hier? M05Pr1mty
Ich kann nicht sicher sein, was das ohne weitere Informationen verursachen würde. Vielleicht solltest du eine neue Frage mit allen relevanten Elementen erstellen (wie z. B. dem Installer usw.). Ich würde jedoch zuerst sagen, dass Sie zunächst einen Dienst erstellen, der nur ein normaler leerer Dienst ist, und sicherstellen, dass er ordnungsgemäß installiert und ausgeführt wird (also überhaupt keine Logik). Anschließend fügen Sie den Castle-Teil hinzu, der die ServiceBase registriert, und stellen Sie sicher, dass funktioniert und fügen Sie dann die WCF-Bits hinzu und stellen Sie sicher, dass dies funktioniert. Dann haben Sie die Zutaten für eine gute Frage (hören Sie einfach auf, wenn es nicht funktioniert) oder es funktioniert einfach und Sie haben es gelöst. kmp

Verwandte Fragen