Guidelines for hosting VisualStudio projects on github - c#

I'd like to host some of my C# VisualStudio 2010 projects on github. I'm guessing that it's good practice to at least add a minimal .git/info/exclude file. For my FluentWpf project, I've got this in my exclude file:
FluentWpf/bin/*
FluentWpf/obj/*
Are there any other best practices to follow before checking my projects into git?

You can use GitHub's default .gitignore for it:
https://github.com/github/gitignore/blob/master/VisualStudio.gitignore

If you happen to use Git Extensions, it has its own default .gitignore. In Visual Studio just go to Git menu->Edit .gitignore and click "Add default ignores".
Before making the initial commit I think it's also a good idea to decide on how you're going to treat line endings.
As you probably know, Windows uses a combination of CR-LF ASCII characters to denote the end of a line, while UNIX systems use an LF character alone. If your project is going to be developed only on Windows, I don't think it makes any sense to use the UNIX endings, so I would make sure the core.autocrlf option is set to false. If your project is going to be edited both on Windows and a UNIX system, you may set it true - then the repository will internally store all line endings as LF characters, but files on your disk will contain CRLF.
These are at least the choices I would make, someone else might do differently. Whichever option you choose, CHOOSE IT NOW, because changing it later may be problematic.
Git Extensions allow you to change this option in GUI: Git->Settings->Global/Local settings tab, "Line endings" groupbox.
Make sure all developers in your team have the same setting on their machines.

Related

Apply Visual Studio Quick Actions and Refactorings across entire C# solution

I am trying to cleanup/refactor a legacy C# solution and am therefore exploring options how certain refactorings or quick actions could be applied for the entire solution.
For example, Visual Studio 2017 offers 'Replace xxx and xxx with property' and 'Use auto-property' actions, which I can apply via the lightbulb icon for individual classes and methods/properties.
How could I apply these to the entire application or semi-automatically iterate all occurrences (300+) and apply these?
I am open for all options - command line, powershell, VBA, even VISX-development.
I do not want to re-develop the refactoring itself and I don't think that a simple find&replace will do either.
When the quick action window is visible, you can apply the selected fix to the single instance, or across the entire document/project/solution:
If you apply each identified fix across your solution (or project) then you should only need to process each suggestion once, as the first one you change will apply to all further instances.
Alternatively, you could use the dotnet Format tool to apply a set of specific formatting rules to your project via the command line, although this depends upon you having an editorConfig file with your rules defined.
Have a look at the EditorConfig. What you're looking for is the Language Conventions topic and you can flag an action as silent (synonym for refactoring in v15.8):
# $slnRoot\.editorconfig
[*.cs]
dotnet_style_prefer_auto_properties = true:silent
Then when you run across that action in your code, you can apply the quick action to your entire solution, file, project, etc.
Note: there have been some bugs with EditorConfig in VS2017. I've had to close the solution and restart the IDE to get changes to take sometimes.

Use tabs for indentation but save with spaces in Visual Studio

I was wondering if it's possible to use tabs for indenting my C# code in Visual Studio 2013, but save the file with all tabs converted into spaces automatically. I know this can be changed in settings and then autoindenting used to fix it to the right one, but this isn't automatic.
The reason behind this is that I am currently working in a group where spaces are preffered way of indenting code, but this setup isn't convenient for me - having to click backspace 4 times after an exceeding tab (or undoing - which is almost the same inconvenience, albeit not that much) is quite annoying.
I don't want to interfere with my group's setup (nor could I, actually), but would like an easier way to traverse my code locally. We use Git for project sharing, so maybe if this cannot be made in VS maybe Git can do it?
Note: I searched Stack and Google, but couldn't find adequate answer due to arguments over which indentation technique is better. This post is not supposted to start another discussion about this either.
Since you're using Git, you could try checking out tabs and converting to spaces on checkin. This might cause issues of its own, but it might also solve your problem. This question should tell you how to do that if you're interested. It deals with Python, but I imagine it would do the same for C# just fine if you replace .py with .cs. Here's the accepted answer for completeness:
In your repository, add a file .git/info/attributes which contains:
*.py filter=tabspace
Linux/Unix
Now run the commands:
git config --global filter.tabspace.smudge 'unexpand --tabs=4 --first-only'
git config --global filter.tabspace.clean 'expand --tabs=4 --initial'
OS X
First install coreutils with brew:
brew install coreutils
Now run the commands:
git config --global filter.tabspace.smudge 'gunexpand --tabs=4 --first-only'
git config --global filter.tabspace.clean 'gexpand --tabs=4 --initial'
All systems
You may now check out all the files of your project. You can do that
with:
git checkout HEAD -- **
Although I too prefer tabs, I also suggest finding out how to use your tools effectively with the project's style. Maybe you could just find a way to make backspace delete sets of 4 spaces when found?
Since your primary issue deals with formatting concerns, I would recommend using Format Document (Ctrl+K,Ctrl+D or Edit>Advanced>Format Document or Format Selection) to fix this.
Its fast and will correct indentation for the whole file/section at once, and you don't have to worry about altering the IDE save behaviors.
If you are trying to keep everything well organized as-you-type-it, you may not be using the provided tools efficiently.

Deploying branches and maintaining configs in VS2010 / VSOnline

I'm trying to get one of our internal c# click once applications into VSOnline for source control to allow access for an external developer.
I think I've got it set up and working in the Source Control Editor, but am having trouble working through how to actually use the setup day to day.
I've got some git experience but zero TFS experience, but went with the TFS option as I thought it's more likely developers are familiar with it than git.
What I'm trying to achieve is 3 branches; Main/Trunk, Dev and Release and be able to deploy at least Release and Main. Release is for external clients, Main for internal clients.
At the moment my Source Control Explorer looks like;
DefaultCollection
-->Name of project
---->(Branch icon) Dev (created as a Branch from Main)
---->(Branch icon) Main
---->(Branch icon) Release (created as a Branch from Main)
2 things;
In terms of use I'm not really sure how to swap between the branches for coding / making changes? Do I just open the solution file for the branch I want to work on then save all changes as I go, then commit that as a changeset? Or is it a matter of manually checking the file out, working on it, then checking it back in again?
Given it's a ClickOnce app; each branch is deployed to a different IIS site, meaning diff app identies, paths and settings. Am I right in using branches for this or is there a better way? I'm worried about someone committing the wrong file and causing a mandatory uninstall/reinstall of the app.
Any pointers / docco greatly appreciated; just note I'm using VS2010.
Thanks,
Liam
How do I swap between branches
If you're used to GIT than the 'heavy weight' branching in TFVC can be a bit confusing. There is no real "Switching between branches" as you've encountered. You map a branch to a local folder and by opening the files there you're "working on that branch".
As Lee points out you can create separate workspaces for each branch, which will isolate the work areas for each. If you're using a Local Workspace, each workspace gets its own "/tf$" folder, the TFVC equivalent of the "/.git" folder.
There's a couple of documents on MSDN that explain this in a little more detail:
Set up TFVC
Create one or more workspaces
Optimize your workspaces
How do I check in
A changeset in TFVC is the equivalent of a commit in Git, it's a logical set of changed files that is committed/pushed as a whole, or not at all. But just as in Git, you can commit all the changes to your local work area at once, or you can exclude certain changes from the first commit and stick those in a second.
In TFVC you'd normally try to commit a logical set of files that fixed the bug, achieved some goal etc. Though it's still possible to check-out/check-in files individually, chances are much higher that you'll actually cause the sources in the main repository to be in an inconsistent state that way.
See
What is a Changeset
Check in your work
Shelving your work
As for your second question
Depending on how far you'd want to go, you could setup Team Build to actually build the application and to take the configuration from a specific location during the build process. That way you wouldn't have to store the configuration for your production environment with the development settings. Configuration files can contain sensitive information, you might not want to have them in Source Control, except for the development versions.
You can also store the config files in a special folder in each branch and make sure that each time you merge them, they're updated accordingly.
And you can, as Lee mentions, look into Config Transaformations. which apply some XSLT to your config file in the build process. That way you can have multiple config files stored in each branch and the selection of your "Configuration" in Visual Studio will define what the final config looks like.
See:
Tricks with app.config files and click once
The _PublishedApplication Nuget package
SlowCheetah
In terms of use I'm not really sure how to swap between the branches for coding / making changes?
I recommend creating separate workspaces for each branch. This way you won't accidentally check in release code when you are trying to check in dev code. Also, when you want to switch which branch of code you are working on, you switch your workspace. This should keep things "cleaner" and easier to work with.
Do I just open the solution file for the branch I want to work on then save all changes as I go, then commit that as a changeset? Or is it a matter of manually checking the file out, working on it, then checking it back in again?
You shouldn't have to manually check it out. If I remember correctly, it will default to auto check out when you start to make changes. You can check code in however big of chunks as you want. But make sure if you are checking in changes to ClassA.cs that reference needed changes in ClassB.cs, you check that in as well. You don't want to leave the source code in a broken state for the other developers.
If you start working on something and have to suspend that work to do some other task that rose in importance, shelve your work instead of letting your workspace get cluttered up with half done work that makes it difficult to manage check ins.
Given it's a ClickOnce app; each branch is deployed to a different IIS site, meaning diff app identies, paths and settings. Am I right in using branches for this or is there a better way?
I'd look into using web.config transformations for this. You'll still want multiple branches but to separate tested/completed/developing code from each other.

Determine SVN working copy revision from C#

I'm writing a small console tool in C# that needs to know the revision number of an SVN working copy directory to process other data with this number. I already have support for SVN 1.4 to 1.6 by directly reading the entries file in all .svn directories. But SVN 1.7 has changed that to use a single .svn directory with an SQLite database in it.
What's the best method to determine the revision number of a working directory?
I've just tried to use SharpSVN, but it's largely undocumented and I can't figure out how to use it. It's also very huge with 5 MB and potentially several DLLs.
I can't find a simple SVN command line client that is freely downloadable. Also, last time I've seen one, it was huge and consisted of numerous files which is not exactly portable. (It would be great if my tool would only come as a single .exe file.)
Another option would be to use an SQLite library (available as a single separate DLL) and dig into the database myself. I've already done basic research on this but I'm not sure how to detect uncommitted modifications.
TortoiseSVN, which is likely already installed on the machines that will be using my tool, can't be used because it contains everything in a single GUI application, no DLLs that I could reuse.
If you don't want SharpSVN and work with Working Copy, then in 99% host may have SVN CLI-tools.
Check callability of svnversion and call it svnversion <PATH-TO-WC>, intercept output
I use Tortoise SVN's command line tool called 'SubWCRev' for this purpose (http://tortoisesvn.net/docs/release/TortoiseSVN_en/tsvn-subwcrev.html). It allows to determine latest revisions, commit date and more... The drawback of this solution is that this tool work with files, so you will need to define template file and parse tool's output file. This works good for me though.

Can I have global preprocessor definitions in C# library?

In C# you can have conditional compilation by using macros similar to the C/C++ syntax. This would enable the following to happen:
#define MYMACRO
....
#if MYMACRO
//some C# code logic
#else
//some other C# code logic
I need to define some macros in a dedicated file in a C# library project, and I need these macros to be visible inside the entire library, once defined. The problem is that the above code works only for a single file.
Another way I know to work around this, is to add the macros to the build command. This would take care of defining the macros for the entire .dll and I will have the #if - #else checks working wherever I want inside the library. The issues with this approach is that I want to be able to maintain the macros easily. Having them in a file inside the project will be perfect. I'd like to have some comments inside too, so that I will know what each macro is doing. This will not be applicable if I have to pass the macros as build parameters. Another reason is being able to turn a macro on/off by simply commenting it and examining the behavior.
Is there a decent way to achieve my requirement? I'd prefer not to deal with any build automation tools like MSBuild, NAnt or anything like this, still if no other way is possible I'd appreciate an advice which one you consider a better choice.
You #define them for an entire project with Project + Properties, Build tab, "Conditional compilation symbols" setting. This sets the <DefineConstants> element in the project file. You override this property with msbuild by giving it the /property:DefineConstants="MYMACRO" command line option.
I'd also advise putting the macros in the project settings (csproj file) as #Hans Passant suggests.
If you need the defines documented, you could add a documentation file to the solution explaining what the settings mean.
If there aren't too many variants, you could define a new project configuration for each one. That will allow you to pre-configure the necessary list of #defines for each variant, and then simply switch between them from the configuration combo box in the toolbar. If you want to temporarily disable one option, you could duplicate the current configuration and remove the #define, then delete the config later when you've tested it.
The next option I can suggest to make it "easier" (by combining the settings and docs into a single file as you've suggested) would be to use a simple text file (settings + comments) to configure the project, and spend 15 minutes writing a quick c# app to read this file and write the settings it contains into the .csproj file - it's just XML so should be a trivial app to write. You'd be able to easily tweak this file and run your updater app to chnage the project settings. If it's something you will do often, spend 30 minutes on it and add a UI with checkboxes to choose the settings more easily.
The concept you're describing sounds rather odd, though. The point of a library is usually that you have one standardised lump of code that can be shared by many clients, so changing these sort of defines to reconfigure the whole library a lot is not something that I'd expect to need to do very often. Perhaps you have good reasons, but it may be worth reviewing why you need to solve this #define problem.
(e.g. If you have lots of customers who need different variants of the "library", the best approach will be to use configurations (described above) to allow you to build all needed variants in a batch build. If you are just trying out lots of different algorithms/techniques then can you redesign chunks of the library so that you can restrict the impact of most #defines to just to a single .cs file so they no longer need to be global? Perhaps the library shouldn't be in a single dll, or a plug-in architecture is needed to allow you to pick and choose the "modules" that are included within the library)
C# “preprocessor” directives don't work the same as C preprocessor directives. The most important difference for you is that there is no equivalent of #include. It's not needed under normal circumstances, because C# doesn't have (or need) header files. I don't think what you want is possible, unless you somehow create your own preprocessor or read the file with #defines and make them into parameters of msbuild.
But I think it would be easier for you to use more object-oriented approach: encapsulate the different approaches into classes and use them. To specify which one of them to use, you could use dependency injection. That means you would have to ship a DI library along with your library, but I think that's a price worth paying.
Also, this approach would alleviate a problem with conditional compilation: specifying different set of symbols may break the build in unexpected ways.
Using GUI
Open the project in Visual Studio
Right-Click on the project file in the solution explorer go to properties
Go to Build tab and Make sure you select the All Configurations in the configuration drop down
Make sure selected the All Platforms in Platform drop-down
Type the Preprocessor Definitions you want in the Conditional Compilation Symbols text box separated by semicolon
To the Project file
Open the project file in a text editor
Copy and paste this code to end of existing PropertyGroup
<PropertyGroup Condition="'$(VariableName)'=='VarableValue'">
<DefineConstants>PDEF1;PDEF2;PDEF3</DefineConstants>
</PropertyGroup>
If you not required to add a condition, delete the Condition="'$(VariableName)'=='VarableValue'" part
Save the project file and open from Visual Studio
From: https://codeketchup.blogspot.sg/2018/04/how-to-add-project-level-preprocessor.html

Categories

Resources