Link to home
Start Free TrialLog in
Avatar of itnifl
itniflFlag for Norway

asked on

Compile a dll that always runs its code as if System.Diagnostics.Debugger.IsAttached

Is it possible in Visual Studio to compile a dll  that always runs its code as if System.Diagnostics.Debugger.IsAttached?
I am using C#.
Avatar of AndyAinscow
AndyAinscow
Flag of Switzerland image

Does code actually run differently when that is attached?  (I doubt it does)
Avatar of itnifl

ASKER

Yes, my code is written to check for it and bypass data collector tasks that are not available while debugging. Instead static data is returned so that it may be used for debugging purposes and further development of this code and code that uses the solution.

For now I have added an extra boolean to my if() sentences checking if System.Diagnostics.Debugger.IsAttached, but I would prefer to not mess up my code like that. Would be better to trick the compiler to always answer true on System.Diagnostics.Debugger.IsAttached as if we were always debugging and then turn this off later and recompile for dependent projects when this is not needed any longer.
SOLUTION
Avatar of AndyAinscow
AndyAinscow
Flag of Switzerland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
@James
>>If however you want to have something that works on the whole project, there is a simpler approach.

Erm, your 'simpler' approach is what I suggested.  Two configurations for compiling with a flag set at compile time available for the complete set of files.
@Andy

Yes you suggested conditional compilation, but you did it through a compiler option, something that, in my experience, very few programmers use because most of these can be set more easily through the project's properties.

And the link you gave show how to define the options in the code, which is a pain when you need to do it in many files, when you have to change the values often, and/or when you have many configurations with different combinations of values for the same options.

I simply wanted to point to a third way of doing it, the one I almost always see when reviewing code. And add a more complete idea of how to use it in code, with a brief example that is not confusing as the one in your link. It can lead one to think that the thing is always used in combination with DEBUG.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
The Conditional attribute is possibly the best way to go when you need to remove complete methods. But in my experience, it's not often that I had to do that. I use conditional compilation very often, and almost always end up with situations where it is not convenient.

The #if has 3 advantages over it.

The first one is that it can be applied to only part of a method. Often, a #if will deal with only one or two lines. Creating methods for these situations would be overkill.

It also has the possibility of having a #else, which is also something that often happens with conditional compilation. Having to create 2 methods with different attributes to do so would also, in my opinion, be overkill, and make the code less fluid.

The editors gray out code that is not compiled with the configuration that is currently selected. This makes it automatic and thus easier to see what will really be there when the application compiles. With the attribute, you have to be very careful of spotting the attribute in order to see that a method is there in the code but will not compile.
The first one is that it can be applied to only part of a method.
There's a fine line to this being advantage, I think. Consider the following:

namespace ConsoleApplication67
{
    class Program
    {
        private static decimal _account = 100;

        static void Main(string[] args)
        {
            decimal toDebit = 10;
            decimal balance = Withdraw(toDebit);
        }

        private static decimal Withdraw(decimal amount)
        {
            bool accountHasFunds = CheckThatAccountHasFunds();

            if (accountHasFunds)
            {
#if DEBUG
                DebitAccount(amount);
#endif
            }

            return _account;
        }

        private static bool CheckThatAccountHasFunds()
        {
            return (_account > 0);
        }

        private static void DebitAccount(decimal amount)
        {
            _account -= amount;
        }
    }
}

Open in new window


Oversimplified example, but it should stress the importance of care in using that functionality in such a manner.
Most of the time, code for debugging is just adding a few lines of code that are not there in release, something like logging information that is not logged in normal application use, using a different path or connection string for test data or server, changing the value of a constant.

It is usually not something that apply to a simple call to a method. And as I said sooner, in such a situation, the Conditional attribute is probably the best thing.
Avatar of itnifl

ASKER

Thank you gentlemen, all your solution suggestions were highly valued.
@Kaufmed.
I'm having trouble thinking about how to use your suggestion (turning complete functions on/off rather than isolating blocks of code with #if, #else, #endif ) for this case - using static data for development/testing rather than 'real' data.  Can you give a quick air code / logic of how you would do that.
@Andy

Are you referring to something other than what I posted above?
@kaufmed
The question as I understand it is about how to supply a default/standard set of data under certain conditions, at other times to use 'real' data.  I just can't see an easy way to do that by turning complete functions on/off via compilation - which is what your suggestion refers to.

ps.  Your example above doesn't change the source, it just runs an action automatically on what is provided.

pps.  Having written that a possible but rather ugly way has come to mind.

[Conditional("STATIC_DATA")]
private void ProvideStaticData()
{
    //generate the standard data
}

xxx()
{
  //read data from database
  //fill with actual sales values

//now throw all the above away should the following function exist
  ProvideStaticData();
}
The question as I understand it is about how to supply a default/standard set of data under certain conditions, at other times to use 'real' data.
OK. I read this as a logging question. But I read things too fast a lot of the time. You could probably do this with some static variables, but that would very hacky, and potentially error prone, I think. The #if in this case is probably both safer and cleaner.

Your example above doesn't change the source,
I agree, but maybe I don't understand what you are saying.
@kaufmed
This is from the follow up comment to the question, providing clarifying information about the task in hand:
Yes, my code is written to check for it and bypass data collector tasks that are not available while debugging. Instead static data is returned so that it may be used for debugging purposes and further development of this code and code that uses the solution.