问题
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