質問

I have .NET Windows Forms application that has gotten so popular (just kidding) that now I need to make 3 more pretty much exactly like it, with the exception of the icon, some titles and handful of labels.

I've got everything in place using code like:

#if CCA
  myLabel.Text = "Version A";
#endif
#if CCB
  myLabel.Text = "Version B";
#endif
...etc...

I've set up a Visual Studio project/solution "configuration" for each of my conditional compilation symbols (e.g. CCA, CCB, etc.), and also I have some #if .. #endif blocks in my AssemblyInfo.cs file to handle the Assembly Titles, etc. When I need to build I just change configurations, update my icon (I've not figured a way to make the icon conditional), and rebuild. The advantage here is that I have a single code base and if I need to make changes I only need to make them one time.

I am pretty happy with the solution, but since I just sort of hacked it together myself after seeing conditional compilation used in the NLog source code a couple weeks back I wanted to double check with the group mind here to learn:

Is what I'm doing an accepted way of accomplishing this?
Is there a better way? Any downside?

Thanks!

役に立ちましたか?

解決

I'll suggest to keep away from conditional compilation. because they create "Dead Code", meaning code that be in place but doesn't compile(just like comments).

It is completely fine if you're just changing Assembly Titles, etc but then if you're changing a feature based on compilation argument you should think of a better way.

Assume you have

private void SomeMethod()
{
    //Some code
    #if CCA
       DoSomething();
    #endif
}
private void DoSomething()
{ }

So what happens when you're refactoring your codebase and changed DoSomething to DoSomethingInteresting when CCA switch is turned off. What happens? You have broken your code. but still it will compile, you'll not realize it till you turn CCA switch on. Brittle isn't it?

I'll suggest you to move all the business logic, UI, etc in a library(dll) and then create a "BootStapper" project which is an executable which refers that dll and starts the application.

create a static class namely ApplicationConfig or similar like this; Set the necessary properties from bootstrapper itself.

public class ApplicationConfig
{
    public static string VersionText { get; set; }
}

Then you can simply do

myLabel.Text = ApplicationConfig.VersionText;

What benefits you get?

  • You can change Assembly Titles, etc
  • You can change Icon
  • You eliminated brittle code
  • etc

What is the dis advantage

  • You need many bootstrapper projects (that's fine)
  • You compile the feature to someone which they don't need

他のヒント

Instead of using conditional compilation, I would suggest reading the values from a file.

If there are not very many, app.config is a good place to store that information. If you do not want to have the configuration information visible in plain text, you could store one configuration file per version as resources in the EXE, and load the desired one at runtime. You could use app.config to indicate which version should be used.

Either way, when the app first loads you would read the configured values and initialize the relevant controls with those values.

That way, there is just one version of your program to be distributed with just minor changes to the app.config file.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top