如何重新启动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调用以重启服务,并在服务启动并返回请求后重新加载页面。
答案 0 :(得分:5)
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)
{
}
}
}