Refresh.NET - code migration tool for .NET projects
Tags: csharp, dotnet, migration, refactoring
Published: 2020-05-01 18:08:29

---
title: Refresh.NET - code migration tool for .NET projects
published: true
description: 
tags: csharp, dotnet, migration, refactoring
---

## Shareable refactorings

Refactoring is a term coined by Martin Fowler. It describes an action of changing
the structure of a code without altering it's behaviour.

We are performing refactorings daily in our jobs - we rename, move, change classes and methods. Those refactorings, however, are usually highly specific
to one's projects and will be performed only once.

However, there are three groups of refactorings which can be performed on
multiple projects without knowing their specifics:

* Adaptation to library API changes
* Language version or dialect update
* Language change (e.g. C# -> Java)

In this article we will focus on the first two types of refactoring. Both
of those refactoring types are absolutely independent of the project code itself.

When using a library, we are provided with a set of methods and classes to achieve the functionality of the library. If for some reason the developers of the library decide to change the API of the library, all the projects that are using this library will have to perform the same changes if they want to update the library version. In this case, the library can be both conventional library and a framework, as in essence they both only provide APIs.

Also, all of the projects will be written in some programming language. All the projects will use the same, strictly defined language constructs. And in the case of language evolution, all developers will be able to perform same abstract changes on their projects.

In these cases, wouldn't it be nice if someone wrote and shared all the changes necessary
and all others could automatically apply those changes on their projects? :)

There are a few tools allowing to do that: Eclipse refactoring [scripts](https://help.eclipse.org/2020-03/index.jsp?topic=%2Forg.eclipse.jdt.doc.user%2Fconcepts%2Fconcept-refactoring.htm) for Java and [JsCodeShift](https://github.com/facebook/jscodeshift) for JavaScript. Eclipse however only allows to record high level refactorings to the migration script. JsCodeShift, on the other hand, grants full flexibility by allowing to modify syntax trees, however lacks support for higher level refactorings.

## Refresh.NET

Having done quite an extensive research in this field for my bachelor paper, I have made a prototype in C# which is supposed to migrate .NET projects, since there are no such tools for C# environment which I'm the most familiar with.

Now what do I mean by _migration_? Migration, both in my paper and in the tool, signifies a series of refactorings, **which can be shared and executed** across multiple projects.

Such migrations can be adaptations for library or framework API changes, language
version updates or any arbitrary other refactorings expressed through a change of AST (_abstract syntax tree_).

Everything can be written in one `.cs` file, which can be versioned and shared across multiple projects! Moreover, it doesn't even need to be in any project!

If you happen to need higher level migrations, the tool provides _fluent API_ -based migration builder, which can easily combine multiple prebuilt higher level migrations.

On the other hand, if you need something more specific, like changes for language migration, you are given the plain Microsoft's `SyntaxTree` to work with as you need.

The tool and its detailed documentation can be found on:
{% github https://github.com/tomasmuzas/Refresh.NET %}

Everyone is welcome to suggest improvements, report bugs, etc.!:)

## Feedback

If someone happens to be interested, please provide any feedback here in the comments or on the github repo! :)

Also, have you faced any breaking changes in the libraries that required a lot of manual refactoring? If so, I would love if someone shared it with me and I could see if I can adapt the tool to fit it. Maybe it will save someone a bit of time!