Bulk Refactoring C# - c#

I want to be able to refactor 500 projects at the same time.
I have about 20 solutions and I don't have a master solution with everything because I haven't figured out a way to auto generate it.
Any suggestions?
Thanks
Edit
I've tried slnTools from codeplex to generate a solution and visual studio pretty much took down the entire operating system. Not sure if it was the solution not being generated properly or if it was just a limitation of Windows / Visual Studio.

To create the huge solution, you should be able to start with a macro vaguely like this:
Dim d As New System.IO.DirectoryInfo(System.IO.Directory.GetCurrentDirectory())
For Each f As System.IO.FileInfo In d.GetFiles("*.*proj")
DTE.Solution.AddFromFile(f.FullName)
Next
DTE.Solution.Close(True)
Before you start the mega-refactoring, I'd suggest you use something like NDepend to analyze the dependency structure of the code, and compare it to your goals for refactoring. You'll only need projects in memory that will be affected by a particular refactoring. If you can limit the set that are needed, you'll greatly benefit.
If you can't get them all into memory, you should still be able to partition the work - you'll just have to repeat it. Consider the case where you've got a single class library that is used by ten other projects, and you want to refactor the public interface.
Save a copy of the class library
Load Project 1 and the class library, and do that refactoring. Close the solution.
Restore the class library from the saved copy.
Load Project 2 and the class library, and do that refactoring again. Close the solution.
etc. Finally, keep the last changed copy of the class library. If you really repeated the refactoring, all ten projects should be happy.
I'd also take the opportunity to refactor towards flexibility, so that you won't need to do this again. Accessing the class library through interfaces or facade classes can isolate you from changes in public interface.

What exactly is it you want to refactor? ReSharper is probably the best known tool for large scale refactorings... but whether it is appropriate depends on what you want to do.
You could always download the trial and give it a whirl...

If they all share the same business / data domain libraries, you can refactor that and then update the references in the projects.
More likely you want to create that business / data domain from these distributed projects. I don't know the details, but I'm willing to bet that smashing 20 solutions together won't help you in refactoring out common code.
I would start small, and create a new solution that is your common application bits.
Pull the obvious pieces of common code into that solution, and reference it's compiled dlls in your other projects.
Review your projects and repeat until you have something resembling the structure you are looking for.

I think there is nothing done to satisfy your need.
You could try slnTools to see how manipulate sln files, and merge them into one .sln file.
But I'm not sure if Visual Studio can handle well 500 opened projects.

You may be better of with a smaller number of projects that each have more files in each. It would not be that hard to write a C# programm the created a project file containing all your souce files.
Visual studio may or may not be able to cope with it then...

Related

Best practice for referencing a project or assembly in a solution

I started at a new company which manages multiple projects (around 30). However, all their projects are in one git-repository. I know wanted to split all our projects into one git-repository per project. To achieve that I went ahead and extracted every folder into a new folder, containing it's own git repository.
However, some references were broken. While investigating I found that project referencing was done in multiple ways, dependent on the project
Including the entire solution/project in the current solution.
Referencing the .csproj-file of another solution.
Referencing the built .dll (bin/debug).
In my opinion, the first way should not the way to be, right? This seems like a way too big overhead. So I'm split between 2 and 3, and I would like to hear how you people are doing it?
Looking forward for your input!
It's normal to have code you want to share between multiple solutions.
For this, we use projects like 'Infrastructure' or 'Logging' with their own CI builds. When done, we create a release build which uploads the dll's to a private nuget server.
These projects are than included as dll's in the other projects through nuget and updated when needed. You also don't break other solutions when you change something in your logging, you have to update the logging version first.
What I do is to have a nuget server in the company or you can use Azure DevOps to do that: https://learn.microsoft.com/en-us/azure/devops/artifacts/get-started-nuget?view=azure-devops.
After you set the nuget server you can update/import the packages for each project. So, when you update the code of any project, post it to the nuget server and you can update all other projects.
Your question sounds like "How to split a solution into smaller solutions".
30 projects is not that much, At 30 C#-projects it's just the starting point to split your solution.The solution is the base for the Repository also.
If you analyze the dependencies of C#-projects, you certainly can form kind of clusters,
are there basics- referenced by everything, and almost front end parts, referenced by nothing.
Basic-Projects (Depends from Nothing, but referenced by many) Tend to be more stable and have less frequent changes, it's also more dangerous to change, more danger of braking changes. It's good to make access to them more complicated (=put it in a different solution). You do not change it frivolously, just because you see the source code and you edit it.
The code and architecture becomes more cleaner, since programmers tend to use a wrapper, derived classes or interfaces to do, what they want to do, inside their active solution.
They do not change dependent solutions as fast and easy any more. So it stays more stable.
You can consider a Solution as a product of it's own, as a Library or Final Product.
So splitting projects in the aspect, what is potentially being used in upcoming projects in the next years, and what is being used as a product for one client only.
Suppose you start a new Product next week, what Projects would you most likely include there ? They belong into a library.
It's also simplifying life to new programmers, if you tell them "Just use it, you don't need to dig in the source code", or "get familiar with this solution only" if you group your C# projects into such clusters. They are not so overwhelmed by quantity.
Also the branching is done per solution, you create a branch on one solution per client request, and a branch of another solution to stay up to date with technology. This is much easier to handle with smaller bundles of projects.
Nuget-Server as proposed by others, is a good way to maintain updates. Without a Server you link to DLLs directly. If you do not have many updates, either you invest time in setting up the server, or in copying a few DLL's around, twice a year. One is not more complicated or time consuming as the other. Manual jobs done by different people cause the risk of human errors. But the task "copy all DLL's from one directory to another directory" might still work. Do not reference the output directory from one solution directly to the other solution. Put the "productive DLL" in a separate directory and do your update by saying "yes, I want to update - use it now". "Automated update" just if someone decides to built the other solution might cause trouble.

How to reuse SpecFlow steps from a different solution

I am new to SpecFlow and I am wanting to reuse steps/tests (.feature files essentially) between solutions. I know there is a way to reuse steps between projects in the same solution by adding a reference to the project but I'm not sure exactly how to do essentially the same thing to a different solution. Thanks for any help on this one.
You cant reuse .feature files but you can reuse step definitions and hooks.
You will have to add reference to the project.
Here is the link how to reference a project in Visual studio: Link
I do not think it is possible to use steps from a different solution. You will need to include them in your working solution somewhere to use them. I don't think Visual Studio has the option to let you use inter-solution code unless you have compiled it and reference it within your working solution.
Doing this is a bit of an anti pattern. The reason for having feature files is to talk about WHAT the application does and WHY its important. So feature files should contain things that are unique to your application domain, and there won't be much overlap between projects
When you write features this way even common functionality isn't really worth sharing, because the complexity outweighs the simplicity of doing things again.
For example logging in is ripe for sharing between applications but all you need in a feature is
Given I am registered
When I login
Then I should be logged in
This is so simple that its easier to just write another one for your second application.
Most steps that people have shared other the years are all about HOW things are done e.g. clicking on things, filling in fields etc.. These generally lead to bloated scenarios and again the cost outweighs the benefits.
If you still feel there is alot of shared behaviour between your applications you may have an architectural problem where you need to extract the shared behaviour into its own application, and have your applications delegate responsibility.

Breaking apart a WPF/XAML project while under development

I hope this is not an obscure question. I expect there are several ways people accomplish it and the approach I'm using seems excessively labor-intensive.
How do I break apart a presentation-layer project (XAML/WPF) into several temporary "side-by-side" projects so that I can make enhancements efficiently in VS 2015 and unit-test them quickly? The end result being that, once the unit tests are successful, I combine the projects back as they were again (with a focus on organization rather than developer efficiency).
The problem for me is not one of analyzing the inter-dependencies, not one of identifying project boundaries, and not one of adding the newly created (temporary) project references where needed. The biggest problem I have is with all the silly XAML namespace references (clr-namespace:). They need updating so they will point to the new home assemblies (assembly=) for the referenced resources. This is a ton of overhead and doesn't always have a pay-off since it is temporary work in the first place. Where is the tool to do this for me? And revert it back out afterwards so that I don't accidentally promote temporary XAML changes into source control?
I thought about managing an entirely separate set of sln's and csproj's for WIP development but this is impossible for the same underlying reason based on the way those XAML namespace references (clr-namespace:) work. Also it is hard to do it as a team effort.
More info:
The reason I ask is because we have a number of projects with XAML resources (user controls, resource dictionaries, etc). Some of these get quite large because they are organized in a certain way that makes them a common place to put stuff (ie. all the combobox lookup - ALT-down - windows, or all common data templates, or what-not). Over time it becomes a problem because VS build operations take too long (impacts development efficiency). VS build operations get slower for larger projects:
a project with a centralized list of all data templates is likely to have a lot of things above it in the dependency stack, causing numerous other projects to be rebuilt after every change
any project with a central repository of anything will grow large and take a long time to compile (5 seconds /project is about my limit while I'm actively developing XAML, with a cap at 10 seconds to do the entire build operation and start debugging)
The biggest problem I have is with all the silly XAML namespace
references (clr-namespace:). They need updating so they will point to
the new home assemblies (assembly=)
Generally, ReSharper does great job, when refactorig xaml. It analyzes xaml files, and fixes wrong xml namespaces. However, you would need to go trough all the files, one by one.
You can also use just plain Find/Replace dialog and replace ;assemmly=TempProject with empty string. Write powershell script for that, if you need to do it more often.
And revert it back out afterwards so that I don't accidentally promote
temporary XAML changes into source control?
You just need to be carefull when doing check-ins, compare files with they original version and investigate changes
However, there is only one good solution for you. Split the projects into wpf usercontrol libraries. Not just for testing purposes, but permanently. Try to break your large resource files. Don't use practices like common place to put stuff when working on large projects. Consider using loosely coupled design and IoC (assembly injection instead of direct references) when possible. Create this shared assembly, which all other assemblies will reference. Don't create component that references lot of other components, but let the others inject themselves instead. Take a look at prism for an insipration: http://www.pluralsight.com/courses/prism-introduction

Better to reference a DLL or have multi-project solutions?

I'm still learning .NET (specifically C#), and I'm curious as the advantages of creating and referencing a dll versus having a multi-project solution? I have the opportunity to do either one, but I'm not sure which would be better. The projects that would be dlls are rather small, but will potentially be reused. Should size and reusability be a factor when making this decision? Thanks for any and all help.
You're still technically referencing other assemblies as each project generates an assembly.
One benefit of having a multi-project solution is that you don't need to build two different solutions- if you change code in both projects the whole solutions builds in one step. Also you can debug both projects at the same time (which is possible with separate solutions, but trickier).
Size may be a factor in build times, but unless they are huge it shouldn't be a huge issue. If projects are used by other solutions it may make sense to keep them in separate solutions so you can control the build process better.
Having separate solutions can also help you keep the interfaces constant since it's moderately harder to change interfaces through the whole stack.
Each project will still output it's own assembly, but grouping projects does make debugging and building easier.
If you are confident that you can reuse the individual projects in the future, start with a multi project solution. Design your projects carefully to minimize interdependence. If you do a good job of this, it shouldn't be too hard to separate them at a later date when you decide you want to develop an individual project independently from the whole solution.
If the assemblies aren't going to be shared amongst other projects I'd just have them in the same solution.
If the code is shared between projects that's different. I tend to treat code which is shared between projects the same way as any other third party binary - that is, I take a copy of the DLL at a specific version and reference the DLL.
The advantage of that is that, in 6 months or a year down the line when both projects that share the code are on different release schedules, each one has complete control as to when it takes the hit of updating the shared code and dealing with potentially breaking changes.
If you've just built the shared code directly into your project you're at the mercy of changes any other project requires - not a good place to be!
when you are initially developing the consuming programme i find it easiest to have a multi-project solution. but when later you develop another programme that also consumes teh same dll's, just reference tehm.
I would suggest you to add library project and you referencing project in the same solution. You reference the library project using Project reference. That would help you to debug and maintain your code better.

When do you decide to split up large projects into smaller projects?

When/where do you decide to split a large Visual Studio project into smaller multiple projects? If it can be reusable? when project is too big? (but how big is too big?)
and When you do split the project, do you,
group by database tables
group by similar functionality
other..
Pros of many projects:
Easier to isolate code for unit testing. I like to isolate code that has a dependency on a big external server thing, for example code that talks to the SMTP server gets its own assembly, code that talks to the database gets it's own assembly, code that talks to the webserver, code that is pure business logic like validations.
Pros of few projects:
Visual studio goes faster
Some developers just don't get your vision
about dividing up responsibilities
and will start putting classes
everywhere, so you end up with the
pain of extra projects and the
benefits of putting everything into
one project.
Each project has a configuration and when you make a decision about project configuration, often you have to make the same chagne everywhere, such as setting or changing the strong name key
Pros of many Solutions
You hit the maximum project level later.
Only the stuff in your current solution gets compiled everytime you hit f5
If the project isn't expected to change in the life of your application, why re-compile it over and over? Call it done and move it to its own solution.
Cons of many Solutions
It's up to you to work out the dependencies between solutions and manually compile the dependencies first. This leads to complicated build scripts.
Projects should be cohesive. Logic should be related, and accomplishing a similar goal
This answer will depend on the size of the product you are supporting. In general we organize our projects along domain and logic. And we will divide those even further, the more you divide the more organize you must be, or you are going to hit the dreaded recursive dependency issue.
When I do choose to break up project it is when it grows to be too large or two areas are becoming too similar.
When complexity is rising I do not split by tables, i generally split functionality.
Re-usability is another excellent time to reduce lines of code, as well as introduce a new project. However be careful how many "utility" libraries you introduce because they do have impact on readability/understandability.
I do not think there is a line in sand that says, if you hit 3k SLOC, you have too much. It all is contextual.
I always have several projects (and therefore a solution) , instead of one project with all of my source in it.
In some cases, it is unavoidable because you are using and open source library and want to be able to debug it. But more pragmatically, I typically have my applications provide functionality via plugins. This allows me to change the behavior or offer a user-selectable behavior at runtime. In the non-plugin case, it allows you to update one portion of your program without updating everything. There are also cases where you can provide the main apparently, and only download the modules / assemblies when you need them.
One other reason is that you can create smaller test apps to exercise an assembly, rather than building a very large solution and potentially requiring a user to execute several (and irrelevant) GUI operations before even reaching the part you want to test. And this isn't just a testing concern -- maybe you have less-savvy users in your organization that only want to be presented with the bits that concern them.
When the overall purpose of the project remains the same, but the number of classes is becoming large, I tend to create folders and namespaces to better group functionality within the project. Classes that are coupled to each-other tend to go in the same folder/namespace, so that if I need to understand a given class, the related classes are nearby in the Solution Explorer. I usually only create new projects if I realize that a particular piece of functionality is very different in purpose or if there is a common dependency between existing projects.
I usually wind up with a few relatively small Framework projects that define interfaces for loose coupling between other projects, with larger projects for the different types of concrete functionality. That's always at least one project for the UI and one project for logic and data (often split into two projects if the data layer becomes very large in its own right.)
I move code to a new project, if it has general functionality (theoretically) usable by other projects too. If the project is large, because it represents a complex problem, then namespaces provide a great way to bring order in the code. Here you can for example introduce a (sub-)namespaces for each SQL table, etc. etc.

Categories

Resources