All the refactoring tools for C# and VB.Net that I have seen only consider the source code in a single visual studio solution.
For better or worse, our large (many related programs) system is spread over many solution files, however:
All the code is below a single windows folder.
Our nAnt based build system, builds all files in a windows folder to produce a single dll (bit more complex then this but not important for this question).
Therefore ALL “.cs” and “.vb” files below the single root folder are part of the system.
So I am looking for refactoring and reverse engineering tools that take a single folder as input and act on all files below that folder.
(The tools may need some help to decide what “public” and “internal” means, however most of the time “internal” means “in the same code tree” when a “code tree” is a folder that contains code and any child folders.)
Now I am being greedy, I would like the tools to create a lot of all the refactorings that have been done and to be able to replay the refactorings. Then I could try out ideal and if they work, throw away my code, get the latest code, you do the refactorings and checkin the code before anyone else changes the files. (Likewise for when branches need merging)
In the past I have done what Pratik has suggested and pulled all projects into a single solution just for the purposes of refactoring. Then personally I would use Resharper every time.
Related
I have a relatively large winforms application written in C# .NET 2.0 using Visual Studio 2005. It also uses Crystal Reports. The compiled EXE is ~12 MB. The source code is ~60 MB.
The overall structure of the application is pretty simple.
There is a single SQL Server database behind. The main form of the application doesn't do anything, except it hosts a menu with many items. Most of the menu items open up some non-modal form. Most of these forms are independent. Some forms contain "reports" - a read-only view of some data with a few parameters that user can change and refresh the report. Some forms provide an editable view of data. Essentially it is a DataGridView(s) with parameters to filter/limit what is shown and with buttons to add/edit/delete a row. Usually the grid itself is read-only. An Add/Edit command usually opens up a separate modal form with the list of fields from the selected row to edit.
There are ~250 forms in total in the application.
All source code is in the single solution and there is single project in the solution.
There are few folders that group the source code of some forms together logically. Say, Sales, Finance, BizDev, etc.
The problem that I face is that if I make any slightest change in any file C# compiler recompiles everything. For example, if I change one line in one file and do "build solution" it takes 35 seconds to compile. If I do "clean solution" and then "rebuild solution" it still takes same 35 seconds to compile. The computer has 16Gb of memory, SSD disk and Intel Core i7, so there is not much room in improving the hardware. I tried to create a RAM drive and put the source code there. It didn't affect compile time at all. Most likely, these 60MB of source code are all in the Windows cache anyway with 16 GB of memory. In C++ world C++ compiler recompiles only the file(s) that is changed, but C# recompiles everything. Also, it uses only one core of the CPU out of 8. Also, the Visual Studio itself can't be used during C# compile time. In my case after I press F7 the VS code editor becomes extremely unresponsive. As I try to move the cursor around the code while the compiler is running it can take seconds to move from one line to another. I'm not even typing anything, just moving the cursor around to review the code.
My question is: if I somehow break this monolithic project into several smaller projects by simply moving logically related forms into separate projects, would it decrease compile time?
As most of these 250 forms are independent it should be possible to NOT compile all of them when only one of them changes.
What would be the best approach to structure the whole thing in Visual Studio if my primary goal is to reduce everyday compile time?
UPDATE:
Just to clarify, I use the term "solution" for SLN file and "project" for CSPROJ file.
I should have mentioned it at the start. When I was searching the web for "how to speed up C# compilation" I came across a lot of posts where people had solutions with many projects in them (70-100). Quite often in such cases it was recommended to reduce the number of projects. Also, there were some recommendations about specific project settings and how they affected the compiler performance. Seeing such problems with other people made me think that having many projects introduces significant overhead to compilation and general VS IDE performance.
Here I have an opposite situation. I have only one project in one solution. Having C++ background it looks very strange to me that C# compiler has to recompile everything every time. I hope that there exists some balanced approach that would allow C# compiler to compile only those files that have changed, thus reducing compilation time in everyday development when I focus on a small part of the whole project.
At the moment the project compiles without warnings.
If you say (from your experience) that C# compiler in VS2013 supports incremental compilation out of the box, I would consider switching from VS2005. If you say (again, from your experience) that indeed having 10 independent projects plus 1 main project for the main form in one solution instead of 1 big project in one solution would usually result in recompiling only two small projects, I would give it a try. If I follow this path of splitting the code into smaller projects I would like to know what are the "gotchas"/some obscure settings to look for, so that the VS and compiler performance would not become worse.
Also, I would appreciate if you could highlight the best approach to configuring the whole solution in VS. For example, should all these small projects compile into a single big EXE, or each small project should compile into a separate DLL and instead of one big EXE I would end up with a dozen DLLs and a small EXE? I don't even know if both of these options are possible. Maybe there are other options.
I would appreciate your ideas.
Thank you.
Firstly 35secs is not that long for a compile of a "large" project. The projects and files in those projects shouldn't be about minimizing compile time, it should be about packaging and managing dependencies.
Compile times depend on a lot of things.
Solutions with multiple projects can skip the compilation of projects when nothing has changed, however if you change code in a project early in the build order, it can trigger a recompilation of everything. Meaning in some situations compile times could be quicker, in others they might be slower.
If you have a lot of code that is rarely changed one sure way that definitely works is to move that code into a separate solution and as part of the compilation process copy the output DLLs of the solution to a staging area. You can then create file references to those DLLs from that staging area on the file system. When doing this I reference files from mapped network drive or from a drive created with a Subst command. The reason for doing this is to give you the flexibility of changing where your solution is picking up DLLs from easily by remapping the drive to another location.
Furthermore, I would look at separating out business logic from the forms, and putting that business logic into separate projects. Well designed applications usually incorporate an N-Tier design that would logically lend itself to having at least one (usually several) separate projects for each tier of the application.
Yes, it is always safe to have the project grouped logically. Anyway there are other factors that effect the compilation time.
Some points to improve compilation time. When you are not ready to deploy yet
1. If you have a setup project, do not enable the setup project unless you are ready to deploy / publish.
2. Look for warnings in the output window, the less number of warnings the better.
3. When working on one piece of code, exclude the irrelevant forms/projects/files that do not effect the current code
Currently we use Source Safe and start migration to Subversion.
All external SDK(> 500 MB) hold in Source Safe now, and I look for way to move them from VSS
to some repository.
We have C++ (mostly), C# (many), Java (few) projects. Hundreds projects. Only Windows platform.
I a couple several dependency managers but not satisfied:
NuGet - good for .Net but painful for C++
Ivy - not look in depth, but seems not acceptable for C++
First question: what I can check else? It should be easy for using by end developer. Best case - simple build within IDE.
Currently I am inclined to next solution:
Allocate some rarely used drive, like S: and declare it as 'DEV HOME'.
Then place externals here:
S:\SDK\boost\1.30\...
S:\SDK\boost\1.45\...
S:\SDK\oracle\agile_9.0.0.0\...
S:\SDK\IBM\lotus_8.0\...
S:\SDK\IBM\lotus_9.0\...
S:\Tools\NuGet\nuget.exe
S:\Tools\clr\gacutil.exe
Autobuild machine will hold mastercopy of this 'DEV HOME'. Every developer should copy necessary SDKs from autobuild machine to local and create disk with subst.
I can't find big problems with this solution:
Branches. Projects in different branches can contains references to different versions of SDK (boost for example)
Version of external component will not change too frequently, so here will no hundreds of, say, boost versions.
Easy for developers to setup.
Absolute paths supported by any tool.
No problems with disk space if you want use not-so-big SSD drive for sources. (Currently I move my externals to separate drive with help of symbolic links. But for other developers this look like black magic)
Minor problems:
Personally for me it is not beautiful solution.
Disk (S:) can be busy
Can't be uses as is in Linux (but currently we not interested in it)
Second question: which troubles in this solution can be?
Update 1: Why not relative paths.
Is externals should be in one directory up with sources root? :
:
externals/...
branch-root-1.0/project_collection_1/project1/...
branch-root-2.0/project_collection_2/...
Here all projects should be in one place or duplicate externals. Seems not much different from solutions with absolute path.
Externals should be in same folder with sources root? :
:
branch-root-1.0/externals/...
branch-root-1.0/project_collection_1/project1/...
branch-root-1.0/project_collection_2/...
branch-root-2.0/externals/...
Then externals will be duplicate in each checkouted branch. This +500MB for every branch checkout + some additional work for setup them.
Well, this look acceptable, but I do not see how it is beter then absolute paths. Really, I want to know advantages of relative paths, because I am also uncomforntable with absolute paths.
I have gone down the path you have.... it can work. However I suggest you make everything relative paths and spend the time getting your projects sorted for relative paths.
The problem with any fixed directory system and source control is you can branch or have multiple check outs of your projects.
Also, while subversion is good, it is worth considering Mercurial or Git. They allow for a number of different kinds of work flows that subversion doesn't. It takes a bit more work thinking how to structure your repositories, but it's well worth it. It is a big jump from sourcesafe, and from my experience, many people coming from sourcesafe really struggle / dislike subversion / git / mercurial initially. They all require you to understand version control in a bit more detail, but thats a good thing, as it is a very good tool.
I think, if your platform is Windows only and Visual Studio then NuGet is the best one. What I like about Nuget is almost no configuration. For example, you can use Boost library immediately after you install Boost Nuget package to your project.
You don't need to configure include/library paths (your current problem).
It automatically installs/configures/updates packages for your project on other computers as soon as you copy (store in SVN/mercurial) the packages.config file.
It can solve/warning about compatibility problems between packages.
I'm not aware about any good cross-platform solution for this problem.
I have application written in C# WinForms developed in Visual Studio 2010 Professional. I am only developer of this application and I use Tortoise SVN for it. Application is hitting 200k lines and I want to split it into 2 different programs (even change naming of application) as actually application supports 2 different companies/departments so it would be better for me to have them as separate projects. At time of projecting the app it was easier to start since I have used code from old application and added more code to support other company/department hence it was build as one project. But now since the application is mature enough I would like to split it into two or even 3 projects as it no longer makes sense.
How can I do that? Will branching help with this? I read that it's to test out features and merge back again but it's not something I want. At best I would like to have 2-3 separate directories so I was even thinking of simply copying application sources multiple times and delete Tortoise SVN files from the copied applications so I could change their names and Commit them again into Tortoise SVN as new applications and then slowly cut out unnecessary code.
You can branch and then delete in one branch half the project and delete in the other branch the other half of the project, or you can duplicate the repository and do the same (but then you'll lose the "option" of merging back some files), or you can simply have 1 repository for two solutions. You create an empty solution and begin adding projects/files.
In the end there isn't a single "perfect" solution. But none of these three solutions are inherently "worse" than the others.
I'll add that if you split the repositories and then want to "clean" their history a little, it could be complex. As written here: http://subversion.apache.org/faq.html#removal it's complex to remove a file + file history (obliterate as they call it) from a repository.
I would just make two new branches. Then you have the history, and you can compare your current working version against the original.
I believe that this type of functionality is built into JetBrains ReSharper, which I've actively decided not to use (oh stop with your surprised face and gasping). Nothing against ReSharper, I just like my IDE to be as lightweight as possible.
I've seen a lot of examples going in the opposite direction - taking partial classes and putting them into one file - but nothing to split one multi-class file into multiple single-class files. Obviously, I'd like for said macro to add said files to the project, but I don't mind if that's not possible.
Any help on this would be much appreciated!
I have written quite a bit of code of the past few years. I've been using the Visual Studio Development Environment for my C# code, but I wouldn't call myself an advanced user of Visual Studio. I can create projects, create source code, and build/debug the project. I don't use many of the advanced features of the IDE, so perhaps there is a simple way to do what I'd like.
My code is often reused - especially thing like filter tools, custom controls (plots/etc) and some communications code (COM/USB/etc). Every time I create a new project, I end up importing a lot of code that I'll need. This code is copied to the new project directory. If I end up editing that code in some way, I then need to update all of the other versions of that file in my others projects. I'm always having to verify that the code that I am importing is the 'latest and greatest'.
I know it is possible to add code to your project by link, and then you'll update the source file, but I'm curious if there is a better way. My example of a 'better way' is the Allegro Lisp compiler. When you start up Allegro, all of your code is loaded into Allegro, and is instantly available. Then you can start hacking around on anything you'd like, and have access to all of your previous code. When you edit something, and compile it, it is instantly usable in the rest of your projects as well. (Usually even if the program is open!) Perhaps this is something fairly unique to Allegro Lisp?
Are there any ways to do something like this in C#? I'd like to still be able to keep separate projects, but I'd like to share source between them and not have to worry about versions getting out of sync. What does everyone else do when they would like to recycle code?
Thanks,
Giawa
Take some time, work through the code and create different projects, for the likes of filters, plots. Give meaningful namespaces to these assemblies, put the code under source control, use external references to these repos in the source control of your main project, or only import the generated assemblies.
Copying code will lead to errors due to not correcting an error in one place, but correcting it another. Use source control, it's gold.