سؤال

I am making a Nuget package that needs to output a version of code for each MVC version and each .NET version. However, for obvious maintainability reasons, I have decided to use conditional compilation constants in the same source file.

What I would like to do is find a way to replace all of the sections surrounded by compilation constants using the appropriate logic so only the appropriate code remains. For example:

    var alwaysExists = 1;
    #if !MVC2
            this.For<System.Web.Mvc.IFilterProvider>()
                .Singleton()
                .Use<FilterProvider>();
    #endif

    #if NET35
            var someVariable = 100;
    #else
            var someVariable = 200;
    #endif

In the above block of code, if the passed in symbols are MVC4, NET40, I would like a text file generated with

        var alwaysExists = 1;
        this.For<System.Web.Mvc.IFilterProvider>()
            .Singleton()
            .Use<FilterProvider>();
        var someVariable = 200;

If the passed in symbols are MVC2, NET35, the text file should be

        var alwaysExists = 1;
        var someVariable = 100;

The method needs to support all methods of logic such as if, else, if !. It needs to have a .cs (text) file input and a .cs (text) file output.

I have thought of a way to potentially achieve this using regular expressions and some custom code, but before I go down that road I was hoping to see if there is an easier way.

Is there a command line utility, library, or something built into the .NET framework that can accomplish this already?

Clarification

I am looking for a way to deploy code files, not a compiled assembly, to the target project with Nuget. I don't want to have to deploy the conditional compilation symbols to the target project (although I could), but instead exclude all of the conditional compilation logic from the code and process the logic to produce code files that are equivalent to what the compiler would do with the symbols. This is code as configuration and the target project will not need more than a single .NET and MVC combination - deploying the symbols as well only serves to over-complicate things. I am trying to avoid having to manually create and maintain a code file for every single MVC/.NET version combination but instead process conditional compilation symbols to produce the same set of files as if I did.

Answer

I downloaded the C++ pre-processor from http://mcpp.sourceforge.net/download.html and used the command:

mcpp -C -P -DMVC2 -DNET35 Input.cs Output.cs

Note that I didn't use the = as the documentation suggested.

The only real limitation is that if there were #region statements in the code, the command would crash. I was able to work around this by omitting them. It also messed up the formatting of the code a little, but still kept it in a compilable state.

هل كانت مفيدة؟

المحلول

You might have luck using the GNU C preprocessor as this answer mentions.

نصائح أخرى

One option is to move all version-dependent code into separate classes with common interface. And then use conditional compilation once - to create an instance of required class.

That way, you can write something like versionAdapter.RegisterProvider() instead of

this.For<System.Web.Mvc.IFilterProvider>()
                .Singleton()
                .Use<FilterProvider>()
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top