I have two projects and two .exes as outputs of these projects. But I want to create one .exe file that can run both. How can I do this in Visual studio 2010?
Move the code from the second project to Class Library instead of an executable. Reference the new project from the first, and then call the code in the second when the first one runs. Your original second executable would also call the code in the new class library.
Two programs:
namespace ProgramA
{
class Program
{
static void Main(string[] args)
{
// Do stuff A
}
}
}
namespace ProgramB
{
class Program
{
static void Main(string[] args)
{
// Do stuff B
}
}
}
Move the code from the second into a class library:
public class ClassB
{
public void DoStuff()
{
// Do stuff B
}
}
Then call it from your first program and your second program:
namespace ProgramA
{
class Program
{
static void Main(string[] args)
{
// Do stuff A
// Do stuff B
var classB = new ClassB();
classB.DoStuff();
}
}
}
namespace ProgramB
{
class Program
{
static void Main(string[] args)
{
// Do stuff B
var classB = new ClassB();
classB.DoStuff();
}
}
}
Related
I have a command with subcommands. In my application I want it mandatory for the user to specify a subcommand. How should I do this?
(See also https://github.com/remkop/picocli/issues/529)
Update: this is now documented in the picocli manual: https://picocli.info/#_required_subcommands
Prior to picocli 4.3, the way to achieve this would be to show an error or throw a ParameterException if the top-level command is invoked without subcommand.
For example:
#Command(name = "top", subcommands = {Sub1.class, Sub2.class},
synopsisSubcommandLabel = "COMMAND")
class TopCommand implements Runnable {
#Spec CommandSpec spec;
public void run() {
throw new ParameterException(spec.commandLine(), "Missing required subcommand");
}
public static void main(String[] args) {
CommandLine.run(new TopCommand(), args);
}
}
#Command(name = "sub1)
class Sub1 implements Runnable {
public void run() {
System.out.println("All good, executing Sub1");
}
}
#Command(name = "sub2)
class Sub2 implements Runnable {
public void run() {
System.out.println("All good, executing Sub2");
}
}
From picocli 4.3, this can be accomplished more easily by making the top-level command not implement Runnable or Callable.
If the command has subcommands but does not implement Runnable or Callable, picocli will make subcommands mandatory.
For example:
#Command(name = "top", subcommands = {Sub1.class, Sub2.class},
synopsisSubcommandLabel = "COMMAND")
class TopCommand {
public static void main(String[] args) {
CommandLine.run(new TopCommand(), args);
}
}
I have referred AppInitializer always launches android for cross platform tests post
still none of the solutions are helping me out, whenever I run BDD tests by default Platform is getting value as Android.
How can I make it dynamically pick the platform values?
I'm having a BaseTest class that inherited by all test class with decorated with PlatformTestFixture attribute. Then we can start Android or iOS app based on platform parameter that passed in.
public class PlatformTestFixtureAttribute : TestFixtureAttribute
{
public PlatformTestFixtureAttribute()
{
}
public PlatformTestFixtureAttribute(params object[] arguments)
: base(arguments)
{
AddPlatformCategory(arguments);
}
private void AddPlatformCategory(object[] args)
{
// Not needed in TestCloud
if (!TestEnvironment.IsTestCloud)
{
foreach (var arg in args)
{
if (arg is Platform)
{
if (Platform.Android == (Platform)arg)
{
AddAndroidCategory();
}
else if (Platform.iOS == (Platform)arg)
{
AddiOSCategory();
}
}
}
}
}
private void AddAndroidCategory()
{
Category = "AndroidTest";
}
private void AddiOSCategory()
{
Category = "iOSTest";
}
}
[PlatformTestFixture(Platform.Android)]
[PlatformTestFixture(Platform.iOS)]
public abstract class BaseTest
{
Platform _platform;
protected BaseTest(Platform platform)
{
_platform = platform;
}
[SetUp]
public virtual void BeforeEachTest()
{
if (platform == Platform.Android)
{
StartAndroidApp();
}
else
{
StartiOSApp();
}
}
}
public class ChildTest : BaseTest
{
public ChildTest(Platform platform)
: base(platform)
{
}
[Test]
public void SomeTest()
{
...
}
}
Then I can run the test in command line specifying whether to run iOSTest or AndroidTest.
[NUnit] [Test Fixture DLL Path] -include=AndroidTest
OR
[NUnit] [Test Fixture DLL Path] -include=iOSTest
Here is an interesting question: Why does the garbage collection not work for the simple unit test initialization example below? At least for me running VS2013 .NET 4.5 I eventually run out of memory and get a out of memory exception.
The shimmed method is needed, without that the garbage collector works just fine also inside the ShimsContext.
This is boiled down from one of my tests where a large xml file was parsed with several million temporary object creations, eventually leaving me without any memory.
Class under test
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MemoryTester
{
public class Program
{
static void Main(string[] args)
{
}
static void MethodToFake()
{
Console.WriteLine("This is the original method");
}
}
public class OutsideClass
{
public OutsideClass()
{
}
~OutsideClass()
{
}
}
}
Unit test class
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.QualityTools.Testing.Fakes;
namespace Tests
{
[TestClass]
public class MemoryTests
{
protected IDisposable Context;
[TestInitialize]
public void InitTest()
{
using (ShimsContext.Create())
{
MemoryTester.Fakes.ShimProgram.MethodToFake = () =>
{
Console.WriteLine("This is the shimmed method");
};
while (true)
{
//This will never be garbage collected, why?
MemoryTester.OutsideClass nc = new MemoryTester.OutsideClass();
}
}
while (true)
{
//Outside of ShimsContext, we will garbage collect just fine
MemoryTester.OutsideClass nc = new MemoryTester.OutsideClass();
}
}
[TestMethod]
public void AttributeSerializerMemoryTest()
{
Assert.IsTrue(true);
}
private TestContext testContextInstance;
public TestContext TestContext
{
get
{
return testContextInstance;
}
set
{
testContextInstance = value;
}
}
}
}
I have written a custom OnMethodBoundaryAspect called TraceAspect. This aspect checks within the OnEntry, OnExit, and OnException methods whether tracing is enabled or not. I have a central class for reading and writing settings. Both of the two methods Settings.GetLoggingEnabled() and Settings.GetLogLevel() are called from the TraceAspect. They are there, so I reuse them which results in a StackOverflowException.
[assembly: MyCompany.MyProduct.TraceAspect]
[Serializable]
public class TraceAspect : OnMethodBoundaryAspect
{
public override void OnEntry(MethodExecutionArgs args)
{
if (Settings.GetLogginEnabled() && Settings.GetLogLevel() == LogLevel.Trace)
{
// Log the message
}
}
}
Applying the [TraceAspect(AttributeExclude = true)] attribute to the TraceAspect class leads to the same behaviour.
I could write something like this. But this is code duplication.
[assembly: MyCompany.MyProduct.TraceAspect]
[Serializable]
public class TraceAspect : OnMethodBoundaryAspect
{
public override void OnEntry(MethodExecutionArgs args)
{
if (this.GetLogginEnabled() && this.GetLogLevel() == LogLevel.Trace)
{
// Log the message
}
}
private bool GetLoggingEnabled()
{
// copy code from Settings.GetLogginEnabled()
}
private bool GetLogLevel()
{
// copy code from Settings.GetLogLevel()
}
}
How can I tell that the Settings.GetLoggingEnabled() and Settings.GetLogTrace() methods should not be traced, when they are called by the aspect?
You can break the recursion during logging by introducing a thread static flag to indicate that you're currently inside the logging call.
[Serializable]
public class TraceAspect : OnMethodBoundaryAspect
{
[ThreadStatic]
private static bool isLogging;
public override void OnEntry(MethodExecutionArgs args)
{
if (isLogging) return;
isLogging = true;
try
{
if (Settings.GetLogginEnabled() && Settings.GetLogLevel() == LogLevel.Trace)
{
// Log the message
}
}
finally
{
isLogging = false;
}
}
}
I'm writing C++ code that calls C# code. The C# may need to invoke methods back in the C++ code. If both parts were C# I think I would use following mechanism. Please note I pass EventHandler from ShouldBCpp to Csharp instead of registering in ShouldBCpp since ShouldBCpp does not know what csharp points to (& can't change CsharpBase).
public abstract class CsharpBase
{
public abstract void SomeMethodDoingActionInB();
}
public class Csharp : CsharpBase
{
public Csharp(EventHandler f)
{
MySpecialHook += f;
}
public event EventHandler MySpecialHook;
public override void SomeMethodDoingActionInB()
{
if (MySpecialHook != null)
MySpecialHook(this, null);
}
}
public class ShouldBCpp
{
public CsharpBase csharp;
public ShouldBCpp()
{
csharp = new Csharp(NotificationFromClassB); // actually using Activator::CreateInstance
}
public void NotificationFromClassB(object sender, EventArgs e)
{
}
public void Go()
{
csharp.SomeMethodDoingActionInB();
}
}
class Program
{
static void Main(string[] args)
{
ShouldBCpp shouldBCpp = new ShouldBCpp();
shouldBCpp.Go();
}
}
Question is how to write ShouldBCpp in C++/CLI. Bonus points for using delegate :)
Thank you
A simple translation to C++/CLI would look like this:
public ref class IsCppCLI
{
public:
CsharpBase^ csharp;
IsCppCLI()
{
csharp = gcnew Csharp(gcnew EventHandler(this, &IsCppCLI::NotificationFromClassB));
// You didn't show your Activator code,
// but I believe it would translate to C++/CLI as this:
csharp = dynamic_cast<CsharpBase^>(
Activator::CreateInstance(
Csharp::typeid,
gcnew array<Object^> {
gcnew EventHandler(this, &IsCppCLI::NotificationFromClassB)}));
}
void NotificationFromClassB(Object^ sender, EventArgs^ e)
{
}
void Go()
{
csharp->SomeMethodDoingActionInB();
}
}