2011-02-14 80 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

相关问题