How to replace global string before compiling in Visual Studio - c#

Every time I compile my application, I would like to replace a string such as $(Database) with [DatabaseName] in all files within my solution/project.
I looked at Pre-build events and Macros, but cannot figure out how to add my own key value pair to it. The solution has many sql files that are in need of replacement of a particular variable. Can this be done via RegEx? I know I can do a FindAll/ReplaceAll but that does not address the issue of doing this over and over.

Okay, so this probably isn't the best solution, but I think it's gonna be better than trying to find some sort of internal solution to replace all instances of a non-code string at compile-time.
The idea is preprocessor directives. You can use the # operator on any line to add a preprocessor directive like so.
One is if/elif/else:
#if DEBUG
// Access your test database here
#else
// Put your hard-coded database calls in here.
#endif
This way, any build of the Debug branch will execute on your test code, and any Release build will execute the original hard-coded database calls.
You can also use your own custom values with #define, like #define MYTESTVARIABLE, after which sections wrapped in #if TESTVARIABLE ... #endif will execute.
Here's the MSDN page: http://msdn.microsoft.com/en-us/library/ed8yd1ha.aspx
As I said, this isn't the best option - it definitely increases the amount of code - but I think it might be less brittle than where you were going in your head.

In SQL Server or ORACLE you could use CREATE SYNONYM to set the name in code so that the code base always references the same name forever so that you do not have to change your code, you just create a SYNONYM on each server for each table or object.
In all cases like you describe I have found a way without using SYNONYM to remove the need for the code file changes during compile. Thus not needing to ever actually use synonym in situations like you describe. I am recommending you take a different approach to the problem. Try not to modify code on each compile. Usually a config file or runtime tweak is all that is needed.
Also be aware that you may see in generated files "MyDevDatabaseActualName" but in reality you do not have to replace it with the QA or Prod database name. This name you are replacing is a TypeName that was chosen from your initial database connection and only a config file change is needed to point to a new database.

Related

Define a constant with an environment variable value that is expanded during COMPILE time

In my csharp code I need to define a constant where its value is set from environment variable expansion during compile time.
In this example let's talk about any arbitrary string, such as "Hello World".
For c++ there seem to be various approaches. See the following answer, for example: https://stackoverflow.com/a/22828929
Surprisingly I wasn't able to find a similar solution for csharp.
In particular, there seems to be no way to tweak the "*.csproj" file accordingly?
PS:
As mentioned in the answer by Hans Passant below: there is some logic for "DefineConstants", but they only give you some kind of boolean flag, so you can use it for conditional statements such as "#if TESTFOO" in your source code. you will not be able to use the actual value of the environment variable.
One possible "workaround" (to dynamically generate additional source files) is described in the following answer, for example: https://stackoverflow.com/a/4453285
But I'm still looking for an official solution that is more "straight".
The C# build system does not support using environment variables strongly. Somewhat inevitable in C++ builds, its build model dates from the 1970s, but given a pass by Microsoft for C#. It does have a fantastic knack for causing build breaks when you try to rebuild your app a year or more after having finished the project. Or quickly when you try to build on another machine and its environment isn't set correctly. Having all the build config in one place is the superior solution.
But MSBuild supports them, you can refer to an environment variable with $(NAME) in the .csproj file. You can for example set a conditional compilation symbol with it, the kind you test in an #if expression. That requires editing the .csproj file by hand, use a text editor like Notepad. Locate the <DefineConstants> element, there are normally two. One for the Debug build and another for the Release build. A silly example:
<DefineConstants>DEBUG;TRACE;$(USERNAME)</DefineConstants>
And used like:
static void Main(string[] args) {
#if hpassant
Console.WriteLine("It's mine!");
#endif
Console.ReadLine();
}
Oops, testing it a bit more reveals that it also works fine from the IDE :) Project + Properties, Build tab, Conditional compilation symbols = $(USERNAME). Nice.
C# does not support preprocessor macros. The only way to generate/modify source code before the compiler sees it (that is what you want to do) are template/macro expansion engines (like mustache or t4)

C#/.NET and JavaScript: Determining implicit exports and imports of .js file

Is there any way to parse or model the contents of a JavaScript file and determine what undefined references it requires, and what references it exports?
I'm looking for a way to automatically determine the correct loading order of giant collection of JavaScript files for a web app. Each file is essentially a module but many files have strange names and extra snippets of utility-type code; the code and its organization is so obtuse we're going to be doing this manually for weeks if it can't be automated.
This is kind of a broad question, which likely implies a nontrivial solution. A start would be looking at something like Jurassic to see if it lets you look at its AST, and working out what variables in which scope are resolved or not. If these are to run in browser, also consider that in Javascript the global scope is the window object, which you can "import" and "export" through, and this can be aliased to who knows what so you'll need to do some sort of dataflow analysis.
A possible alternative would be looking at the implementation of a minifier (I'd try UglifyJS because it explicitly supports parsing into an AST then builds minification on that), since this sounds like kind of what they need to do when determining which variable names they shouldn't abbreviate. That said minifiers are allowed to be imprecise and accept false positives, which might be a problem for you.

Rename de-obfuscated code

Is there any tools that can rename de-obfuscated code to readable code for .NET dlls ?
OBFUSCATION = convert original variable names, namespaces to non-readable variable name, also changing the control flow to make it hard for crackers to guess the original code
DE-OBFUSCATION = reverse process of obfuscation. convert non-readable variable names, namespaces to readable one like A1, A2 (cause converting back to original names is impossible) make it easy to track and understand the original source code.
You could obfuscate it again, but disable options like overloading. That way members will be named A,B,C,... instead of all being named A (using overloading) or having non-printable names.
Also, an IL-level optimizer can often undo control flow obfuscations and remove dead code designed to crash decompilers.
Once you have compilable code, use Visual Studio's rename refactoring to introduce names. There's no way for tools to automatically guess appropriate names.
No there isn't otherwise why would obfuscation tools exist in your opinion? What you call readable variable names no longer exist in the obfuscated assembly because they have been renamed to non-readable ones and no tool could guess what the original names were.
do you mean looking at code within complied dlls? if so i use redgate's .net Reflector.

Checking for the existence a reference/type at compile time in .NET

I've recently found the need to check at compile-time whether either: a) a certain assembly reference exists and can be successfully resolved, or b) a certain class (whose fully qualified name is known) is defined. These two situations are equivalent for my purposes, so being able to check for one of them would be good enough. Is there any way to do this in .NET/C#? Preprocessor directives initially struck me as something that might help, but it seems it doesn't have the necessary capability.
Of course, checking for the existence of a type at runtime can be done easily enough, but unfortunately that won't resolve my particular problem in this situation. (I need to be able to ignore the fact that a certain reference is missing and thus fall-back to another approach in code.)
Is there a reason you can't add a reference and then use a typeof expression on a type from the assembly to verify it's available?
var x = typeof(SomeTypeInSomeAssembly);
If the assembly containing SomeTypeInSomeAssembly is not referenced and available this will not compile.
It sounds like you want the compiler to ignore one branch of code, which is really only doable by hiding it behind an #if block. Would defining a compiler constant and using #if work for your purposes?
#if MyConstant
.... code here that uses the type ....
#else
.... workaround code ....
#endif
Another option would be to not depend on the other class at compile-time at all, and use reflection or the .NET 4.0 dynamic keyword to use it. If it'll be called repeatedly in a perf-critical scenario in .NET 3.5 or earlier, you could use DynamicMethod to build your code on first use instead of using reflection every time.
I seem to have found a solution here, albeit not precisely for what I was initially hoping.
My Solution:
What I ended up doing is creating a new build configuration and then defining a precompiler constant, which I used in code to determine whether to use the reference, or to fall back to the alternative (guaranteed to work) approach. It's not fully automatic, but it's relatively simple and seems quite elegant - good enough for my purposes.
Alternative:
If you wanted to fully automate this, it could be done using a pre-build command that runs a Batch script/small program to check the availabilty of a given reference on the machine and then updates a file containing precompiler constants. This however I considered more effort than it was worth, though it may have been more useful if I had multiple independent references that I need to resolve (check availability).

Why remove unused using directives in C#?

I'm wondering if there are any reasons (apart from tidying up source code) why developers use the "Remove Unused Usings" feature in Visual Studio 2008?
There are a few reasons you'd want to take them out.
It's pointless. They add no value.
It's confusing. What is being used from that namespace?
If you don't, then you'll gradually accumulate pointless using statements as your code changes over time.
Static analysis is slower.
Code compilation is slower.
On the other hand, there aren't many reasons to leave them in. I suppose you save yourself the effort of having to delete them. But if you're that lazy, you've got bigger problems!
I would say quite the contrary - it's extremely helpful to remove unneeded, unnecessary using statements.
Imagine you have to go back to your code in 3, 6, 9 months - or someone else has to take over your code and maintain it.
If you have a huge long laundry list of using statement that aren't really needed, looking at the code could be quite confusing. Why is that using in there, if nothing is used from that namespace??
I guess in terms of long-term maintainability in a professional environment, I'd strongly suggest to keep your code as clean as possible - and that includes dumping unnecessary stuff from it. Less clutter equals less confusion and thus higher maintainability.
Marc
In addition to the reasons already given, it prevents unnecessary naming conflicts. Consider this file:
using System.IO;
using System.Windows.Shapes;
namespace LicenseTester
{
public static class Example
{
private static string temporaryPath = Path.GetTempFileName();
}
}
This code doesn't compile because both the namespaces System.IO and System.Windows.Shapes each contain a class called Path. We could fix it by using the full class path,
private static string temporaryPath = System.IO.Path.GetTempFileName();
or we could simply remove the line using System.Windows.Shapes;.
This seems to me to be a very sensible question, which is being treated in quite a flippant way by the people responding.
I'd say that any change to source code needs to be justified. These changes can have hidden costs, and the person posing the question wanted to be made aware of this. They didn't ask to be called "lazy", as one person inimated.
I have just started using ReSharper, and it is starting to give warnings and style hints on the project I am responsible for. Amongst them is the removal of redundant using directive, but also redundant qualifiers, capitalisation and many more. My gut instinct is to tidy the code and resolve all hints, but my business head warns me against unjustified changes.
We use an automated build process, and therefore any change to our SVN repository would generate changes that we couldn't link to projects/bugs/issues, and would trigger automated builds and releases which delivered no functional change to previous versions.
If we look at the removal of redundant qualifiers, this could possibly cause confusion to developers as classes in our Domain and Data layers are only differentiated by the qualifiers.
If I look at the proper use of capitalisation of anachronyms (i.e. ABCD -> Abcd), then I have to take into account that ReSharper doesn't refactor any of the Xml files we use that reference class names.
So, following these hints is not as straight-forward as it appears, and should be treated with respect.
Less options in the IntelliSense popup (particularly if the namespaces contain lots of Extension methods).
Theoretically IntelliSense should be faster too.
Remove them. Less code to look at and wonder about saves time and confusion. I wish more people would KEEP THINGS SIMPLE, NEAT and TIDY.
It's like having dirty shirts and pants in your room. It's ugly and you have to wonder why it's there.
Code compiles quicker.
Recently I got another reason why deleting unused imports is quite helpful and important.
Imagine you have two assemblies, where one references the other (for now let´s call the first one A and the referenced B). Now when you have code in A that depends on B everything is fine. However at some stage in your development-process you notice that you actually don´t need that code any more but you leave the using-statement where it was. Now you not only have a meaningless using-directive but also an assembly-reference to B which is not used anywhere but in the obsolete directive. This firstly increases the amount of time needed for compiling A, as B has to be loaded also.
So this is not only an issue on cleaner and easier to read code but also on maintaining assembly-references in production-code where not all of those referenced assemblies even exist.
Finally in our exapmle we had to ship B and A together, although B is not used anywhere in A but in the using-section. This will massively affect the runtime-performance of A when loading the assembly.
It also helps prevent false circular dependencies, assuming you are also able to remove some dll/project references from your project after removing the unused usings.
At least in theory, if you were given a C# .cs file (or any single program source code file), you should be able to look at the code and create an environment that simulates everything it needs. With some compiling/parsing technique, you may even create a tool to do it automatically. If this is done by you at least in mind, you can ensure you understand everything that code file says.
Now consider, if you were given a .cs file with 1000 using directives which only 10 was actually used. Whenever you look at a symbol that is newly introduced in the code that references the outside world, you will have to go through those 1000 lines to figure out what it is. This obviously slows down the above procedure. So if you can reduce them to 10, it will help!
In my opinion, the C# using directive is very very weak, since you cannot specify single generic symbol without genericity being lost, and you cannot use using alias directive to use extension methods. This is not the case in other languages like Java, Python and Haskell, in those languages you are able to specify (almost) exactly what you want from the outside world. But even then, I will suggest to use using alias whenever possible.

Categories

Resources