ServiceStack Selfhosted Application Restart

对着背影说爱祢 提交于 2020-01-01 13:29:36

问题


How can I restart a ServiceStack self hosted Apphost? Setting my AppHost instance to null and disposing of it does not work correctly, it throws the following Exception:

System.ArgumentException: An entry with the same key already exists.

I need to be able to do this to reload settings and start the AppHost without restarting the Windows Service hosting the AppHost

EDIT: Scott and Moo-Juice's suggestions to run the AppHost in a different AppDomain is the correct solution. In order to get past the Cross Domain calls to restart the AppHost, I created a second AppHost which runs in the Main AppDomain and calls the Restart method from Scott's solution. Enabling CORS on both AppHost instances allows for a simple $ajax call to restart the service and reload the page once the service is started and the request returns.


回答1:


Use an AppDomain:

Moo-Juice's suggestion to use an AppDomain is correct. I have included a simple example of how to use an AppDomain to isolate ServiceStack, and allow it to be Started/Restarted/Stopped.

using System;
using ServiceStack;
using System.Runtime.Remoting;

namespace Test
{
    public class ServiceStackConsoleHost : MarshalByRefObject
    {
        public static void Main()
        {
            Start();
        }

        static ObjectHandle Handle;
        static AppDomain ServiceStackAppDomain;

        public static void Start()
        {
            // Get the assembly of our host
            var assemblyName = typeof(ServiceStackConsoleHost).Assembly.FullName;

            // Create an AppDomain
            ServiceStackAppDomain = AppDomain.CreateDomain("ServiceStackAppDomain");

            // Load in our service assembly
            ServiceStackAppDomain.Load(assemblyName);

            // Create instance of our ServiceStack application
            Handle = ServiceStackAppDomain.CreateInstance(assemblyName, "Test.ServiceStackConsoleHost");

            // Show that the main application is in a separate AppDomain
            Console.WriteLine("Main Application is running in AppDomain '{0}'", AppDomain.CurrentDomain.FriendlyName);

            // Wait for input
            Console.ReadLine();

            // Restart the application
            Restart();
        }

        public static void Stop()
        {
            if(ServiceStackAppDomain == null)
                return;

            // Notify ServiceStack that the AppDomain is going to be unloaded
            var host = (ServiceStackConsoleHost)Handle.Unwrap();
            host.Shutdown();

            // Shutdown the ServiceStack application
            AppDomain.Unload(ServiceStackAppDomain);

            ServiceStackAppDomain = null;
        }

        public static void Restart()
        {
            Stop();
            Console.WriteLine("Restarting ...");
            Start();

        }

        readonly AppHost appHost;

        public ServiceStackConsoleHost()
        {
            appHost = new AppHost();
            appHost.Init();
            appHost.Start("http://*:8090/");
            Console.WriteLine("ServiceStack is running in AppDomain '{0}'", AppDomain.CurrentDomain.FriendlyName);
        }

        public void Shutdown()
        {
            if(appHost != null)
            {
                Console.WriteLine("Shutting down ServiceStack host");
                if(appHost.HasStarted)
                    appHost.Stop();
                appHost.Dispose();
            }
        }
    }

    public class AppHost : AppSelfHostBase
    {
        public AppHost(): base("My ServiceStack Service", typeof(AppHost).Assembly)
        {
        }

        public override void Configure(Funq.Container container)
        {
        }
    }
}

Instructions for how to use an AppDomain can be found here.



来源:https://stackoverflow.com/questions/26033083/servicestack-selfhosted-application-restart

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!