2011-02-14 52 views
1

這似乎是一件簡單的事情要做,但我似乎無法在任何地方找到任何信息!我有一個解決方案,它具有在調試時運行在「控制檯模式」下的服務。我希望它在Visual Studio中運行我的單元測試時啓動並「附加」。如何在調試模式下運行單元測試時調用多個啓動項目

我使用Resharper作爲單元測試運行器。

+0

嘲笑測試中的服務,然後再單獨測試服務不是更好嗎? – adrianm 2011-02-15 15:06:16

回答

1

不是直接回答你的問題,但 我們面臨着類似的問題,最近並最終使用AppDomain

的解決方案作爲您的解決方案已經在運行一個控制檯項目落戶這將是很少的工作,使之在新的AppDomain中啓動。此外,您可以在此項目上運行斷言以及部分單元測試。 (如果需要)

請考慮以下靜態類Sandbox,您可以使用它來啓動多個應用程序域。 執行方法需要一個類型,這是一個SandboxAction。 (類定義也包含在下面)

你會第一個擴展這個類,並提供任何啓動操作來運行您的控制檯項目。

public class ConsoleRunnerProjectSandbox : SandboxAction 
{ 
    protected override void OnRun() 
    { 
     Bootstrapper.Start(); //this code will be run on the newly create app domain 
    } 

} 

現在,讓你的應用程序域中運行,您只需撥打

Sandbox.Execute<ConsoleRunnerProjectSandbox>("AppDomainName", configFile) 

注意,你可以通過這個調用一個配置文件,這樣就可以以同樣的方式在啓動項目因爲如果你運行它通過控制檯

還有其他問題請詢問。

public static class Sandbox 
{ 
    private static readonly List<Tuple<AppDomain, SandboxAction>> _sandboxes = new List<Tuple<AppDomain, SandboxAction>>(); 

    public static T Execute<T>(string friendlyName, string configFile, params object[] args) 
     where T : SandboxAction 
    { 
     Trace.WriteLine(string.Format("Sandboxing {0}: {1}", typeof (T).Name, configFile)); 

     AppDomain sandbox = CreateDomain(friendlyName, configFile); 

     var objectHandle = sandbox.CreateInstance(typeof(T).Assembly.FullName, typeof(T).FullName, true, BindingFlags.Default, null, args, null, null, null); 

     T sandBoxAction = objectHandle.Unwrap() as T; 

     sandBoxAction.Run(); 


     Tuple<AppDomain, SandboxAction> box = new Tuple<AppDomain, SandboxAction>(sandbox, sandBoxAction); 
     _sandboxes.Add(box); 

     return sandBoxAction; 
    } 

    private static AppDomain CreateDomain(string name, string customConfigFile) 
    { 
     FileInfo info = customConfigFile != null ? new FileInfo(customConfigFile) : null; 
     if (!string.IsNullOrEmpty(customConfigFile) && !info.Exists) 
      throw new ArgumentException("customConfigFile not found using " + customConfigFile + " at " + info.FullName); 

     var appsetup = new AppDomainSetup(); 
     //appsetup.ApplicationBase = Path.GetDirectoryName(typeof(Sandbox).Assembly.Location); 
     appsetup.ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase; 
     if (customConfigFile==null) 
      customConfigFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; 
     appsetup.ConfigurationFile = customConfigFile; 

     var sandbox = AppDomain.CreateDomain(
      name, 
      AppDomain.CurrentDomain.Evidence, 
      appsetup); 
     return sandbox; 
    } 

    public static void DestroyAppDomainForSandbox(SandboxAction action) 
    { 
     foreach(var tuple in _sandboxes) 
     { 
      if(tuple.Second == action) 
      { 
       AppDomain.Unload(tuple.First); 
       Console.WriteLine("Unloaded sandbox "); 
       _sandboxes.Remove(tuple); 
       return; 
      } 
     } 
    } 
} 


[Serializable] 
public abstract class SandboxAction : MarshalByRefObject 
{ 
    public override object InitializeLifetimeService() 
    { 
     return null; 
    } 
    public void Run() 
    { 
     string name = AppDomain.CurrentDomain.FriendlyName; 
     Log.Info("Executing {0} in AppDomain:{1} thread:{2}", name, AppDomain.CurrentDomain.Id, Thread.CurrentThread.ManagedThreadId); 

     try 
     { 
      OnRun(); 
     } 
     catch (Exception ex) 
     { 
      Log.Error(ex, "Exception in app domain {0}", name); 
      throw; 
     } 
    } 

    protected abstract void OnRun(); 

    public virtual void Stop() 
    { 
    } 


} 
+0

這聽起來很有趣..所以不是在控制檯中單獨啓動應用程序,而是在單獨的AppDomain中的測試初始化​​中啓動它,以便在調試器附加時啓動它?一些代碼會很好。 – 2011-02-15 13:27:50

相關問題