views:

420

answers:

4

I have a large application that i can build through the command line. I want to specify a flag that enables me to compile it into either one of two modes, Actual or Simulated.

So the main issue is, how can i use the preprocessor to programmatically add a reference?

For example:

#if SIMULATED
    include SimulatedFiles;
    myFactory = new SimulatedFiles.simFactory();
#else
    myFactory = new realFactory();

I don't want any simulated files to compiled into my "actual" application. Since there is no "include" directive in C#, i am stuck on how to accomplish this.

+4  A: 

nant/msbuild and dependency injection tool with xml configuration?

Ray
+1 for DI; the most appropriate way to solve this.
John Rudy
+1  A: 

In C#, there is no real preprocessor, as you can read on the C# Preprocessor's documentation.

From the documentation (emphasis mine):

While the compiler does not have a separate preprocessor, the directives described in this section are processed as if there was one; these directives are used to aid in conditional compilation. Unlike C and C++ directives, you cannot use these directives to create macros.

Dan Herbert
+7  A: 

You cannot do this via a C# preprocessor statement because the language doesn't support the notion of references via preprocessor macros.

What you can do is use a msbuild file and alter the set of references added based on msbuild parameters.

JaredPar
+1  A: 

Are the include files your own source code, or third-party assembly dlls?

If they are your own sources, then you can easily use conditional compilation to remove the "simulated" code from your release build, exactly as you have done in your example (just replace 'include' with 'using'). This is common practice with debugging classes for example.

If you don't "control" the source code for the includes, then you can still add a project reference, but if you conditionally compile all the code that uses the assembly, your applicaton won't ever attempt to access the assembly, so it doesn't need to be be present when the code is running.

(Another possiblity that seems less useful for you is to write a "dummy" version of the referenced assembly that you ship in place of the "real" one, or a proxy that calls the real third-party dll in simulated builds only. If it supplies the public classes and methods that you call, you can ship the dummy instead of the simulated assembly to your customers)

Jason Williams