这似乎是一件简单的事情,但我似乎无法在任何地方找到任何信息!我有一个解决方案,它有一个服务,我们在调试时在'控制台模式'下运行。我希望它从Visual Studio运行我的单元测试时启动并“附加”。
我正在使用Resharper作为单元测试运行器。
答案 0 :(得分:1)
不能直接回答你的问题,但是
我们最近遇到了类似的问题,最终使用AppDomain
由于您的解决方案已作为控制台项目运行,因此在新的AppDomain中启动它几乎不会有任何作用。此外,您可以在此项目上运行Assertions以及单元测试的一部分。 (如果需要)
考虑以下静态类Sandbox
,您可以使用它来启动多个应用程序域。
Execute方法需要一个类型为-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()
{
}
}