2014-09-25 31 views
3

如何重新啓動ServiceStack自託管Apphost?設置我的APPHOST實例爲null,它的處置工作不正常,它拋出以下異常:ServiceStack自託管應用程序重新啓動

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

我需要能夠做到這一點重新加載設置並啓動APPHOST無需重新啓動Windows服務託管AppHost

編輯: Scott和Moo-Juice建議在不同的AppDomain中運行AppHost是正確的解決方案。爲了通過跨域調用重新啓動AppHost,我創建了第二個AppHost,它在主AppDomain中運行,並從Scott的解決方案中調用Restart方法。在兩個AppHost實例上啓用CORS允許一個簡單的$ ajax調用來重新啓動服務,並在服務啓動並請求返回時重新加載頁面。

+0

我將自己的服務堆棧實例託管在他們自己的AppDomain中,這使得啓動/停止/刪除/添加服務堆棧實例變得微不足道。 – 2014-09-25 07:37:05

+0

@ Moo-Juice我實際上並沒有想到這麼做,謝謝 – cornelha 2014-09-25 07:46:08

回答

4

使用一個AppDomain:

武果汁的建議,使用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

+1

+1,我的代碼是不同的,但哲學基本上是一樣的:) – 2014-09-25 13:31:52

+0

這就是我所需要的,我建立了一個小測試項目,它工作得很好。現在我只需要解決一些反射問題。非常感謝 – cornelha 2014-09-25 14:20:17

+0

@cornelha沒問題。很高興它是有用的。祝你好運,反思:) – Scott 2014-09-25 14:21:33