ServiceStack自主应用程序重启

时间:2014-09-25 07:35:41

标签: c# servicestack self-hosting

如何重新启动ServiceStack自托管Apphost?将我的AppHost实例设置为null并处理它无法正常工作,它会抛出以下异常:

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

我需要能够重新加载设置并启动AppHost而无需重新启动托管AppHost的Windows服务

编辑: Scott和Moo-Juice建议在不同的AppDomain中运行AppHost是正确的解决方案。为了通过Cross Domain调用来重新启动AppHost,我创建了第二个AppHost,它在Main AppDomain中运行,并从Scott的解决方案中调用Restart方法。在两个AppHost实例上启用CORS允许进行简单的$ ajax调用以重启服务,并在服务启动并返回请求后重新加载页面。

1 个答案:

答案 0 :(得分:5)

使用AppDomain:

Moo-Juice建议使用AppDomain是正确的。我已经包含了一个简单的示例,说明如何使用AppDomain隔离ServiceStack,并允许它启动/重新启动/停止。

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)
        {
        }
    }
}

Screenshot

how to use an AppDomain can be found here的说明。