#if DEBUG vs if (env.IsDevelopment())
Asked Answered
T

5

31

It seems that Preprocessor Directives (#if DEBUG) and ASP.NET Core Environment Name (IHostingEnvironment.EnvironmentName) both could be used when you want to have different behavior in debug/development and release/production. When is it appropriate to use one over the other is there any reason to prefer one over the other

Example with #if DEBUG

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    #if DEBUG
        app.UseDeveloperExceptionPage();
        app.UseBrowserLink();
    #else
        app.UseExceptionHandler("/Error");
    #endif
}

Example with env.IsDevelopment()

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseBrowserLink();
    }
    else
    {
        app.UseExceptionHandler("/Error");
    }
}

Update: This question I am looking for when should use the ASP.NET Core environment name (a new feature of .NET core). This is different then the other question regarding #if and conditional attribute

Trottier answered 12/2, 2018 at 20:27 Comment(8)
Possible duplicate of #if DEBUG vs. Conditional("DEBUG")Infantile
The duplicate is not exactly the same, I know, but the difference standsInfantile
Camilo, There is a question regarding the #if DEBUG with Conditional attribute however here I asking when #if DEBUG is applicable compared to the the relatively new ASP.NET Core Environment Name / app.IsDevelopment. These seem like very different concepts. In fact the ASP.NET core was not even around when that question was asked.Trottier
As I said, the difference is the same. .NET hasn't changed and .NET Core uses the same logic for preprocessor directivesInfantile
Camilo, the pre-processor directives are the same i am more asking when is it appropriate to use the new way in lieu of the preprocessorTrottier
@CamiloTerevinto I strongly oppose labeling this as a duplicate. I am very familiar with both preprocessor directives and ConditionalAttribute; the difference between preprocessor directives and ASP.NET Core environments is a completely different matter. The issue I'm seeing in this question is actually with the answers: they don't really explain the difference, which makes it look like a duplicate. It's also worth noting that ConditionalAttribute does affect the compiler, while environment tests do not; the answer to which you linked would be incorrect for this question.Arnitaarno
@Arnitaarno I'm not sure if you realize my comment was 7 months ago. Also, the answer by RonBeyer is correct, so I'm not sure what you are talking aboutInfantile
@CamiloTerevinto Yes, I realized how long ago it was made. I still oppose it, and I am stating that fact. Ron Beyer's answer is correct, and it differs significantly from the answer to which you linked. Notably, ConditionalAttribute does result in compile-time alterations, while IHostingEnvironment.IsDevelopment does not.Arnitaarno
Z
18

Preprocessor directives are conditionally compiled...

Which means that something like this:

#if DEBUG
    //Do something
#endif

Will only be compiled and checked if the DEBUG symbol is defined (it is defined when the build is set to DEBUG). Additionally, in the IDE the code between the preprocessor symbols will appear greyed out.

This code:

if (env.IsDevelopment())
{
    //Do something
}

Is compiled for both release/debug environments. The key here is that the code exists and the tests are run regardless of the environment being debug/release. In more complicated scenarios this has two effects:

  • The execution of the code may be slower
  • The executable will be larger

Additionally including debug code in a release environment may be giving away some trade secrets or other vital information if released. Where possible try to avoid releasing debug code in release mode.

Zincograph answered 12/2, 2018 at 20:37 Comment(0)
D
15

While the other answers are correct in how the DEBUG precompiler directive works, I think they are missing the point of the question, which is when to use one method over the other.

I have a very specific instance where I MUST use IsDevelopment over #if DEBUG...

As has been stated, #if DEBUG includes the code in compilation for the debug build configuration only and greys out and does not include the code for the release configuration.

The IsDevelopment method is not dependent on build configuration at all, it is dependent on .NET Core environment variables, particularly the "environmentVariables" setting in launchSettings.json in your Properties folder

So you can use this to your advantage... in my case, I have a web application where I want to write to a log file only when debugging, and it is an exception to write to the local directories when running on the web server, so I can't use the #if DEBUG directive.

However, if I dependency inject the IHostingEnvironment into the constructor of my class and set it to a local field, I can test the _environment.IsDevelopment() call and ONLY execute this code when I am running from the Visual Studio IDE

I believe these settings are here by default in launchSettings.json:

"profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },

So in other words, when you want to differentiate further than just being in a "debug" configuration or environment, and want to run specifically if running from the IDE, use IsDevelopment.

Doublecheck answered 13/6, 2018 at 17:40 Comment(0)
M
3

If you'd like to perform a different action on e.g. Development, Staging, and Production environments (which may be the result of server capacity or configuration), that can be done by applying a check using IHostingEnvironment.EnvironmentName.

The '#if DEBUG' method wouldn't allow you to do this because the decision over the code to include within the statement is made at compile time.

Markhor answered 12/2, 2018 at 20:43 Comment(0)
N
0

You can change your configuration environment and only build your application one time using the IHostingEnvironment. This is the ideal way to properly build and test an application.

The pre-processor directives will change the IL at compile time which could introduce some additional risk/hiesenbugs.

Nagana answered 12/2, 2018 at 20:33 Comment(2)
In both cases it causes the code that executes to change and would cause the same risks of bugs.Trottier
@Trottier true, but recompilation has its own risks.Nagana
E
0

With #if DEBUG the code in the non-execution branch will not even be compiled and included in the assembly whereas with env.IsDevelopment() will be. So you can use #if DEBUG or #if WINCE or #if !DEBUG or #if DOTNET45 or any other custom one you chose to define to compile and build for a specific platform that might otherwise give you compilation errors.

Additionally, you can decorate a method with the Conditional("DEBUG") attribute and any code that invokes that method will not be compiled into the assembly.

Exude answered 12/2, 2018 at 20:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.