The Case For .Net Monkey Patching In 2018
You'll Go Bananas For This Idea
July 01, 2018In this post, I am going to attempt an argument for "monkey patching" in .NET and why its time to let go of old arguments and think about the new paradigm the .NET community has entered.
What Is Monkey Patching?
Monkey patching is the ability to affect the internal behavior of an object during runtime. Wikipedia says:
The definition of the term varies depending upon the community using it. In Ruby, Python, and many other dynamic programming languages, the term monkey patch only refers to dynamic modifications of a class or module at runtime, motivated by the intent to patch existing third-party code as a workaround to a bug or feature which does not act as desired.
Applications of monkey patching include:
- Replacing behavior at runtime for testing purposes.
- Extending third-party products.
- Applying a patch.
The Critical Use Case
Let's say you chose to use a Nuget library for a critical task. Time is of the utmost importance, and blocking issues are not an option. You've done your research, investigate the source on GitHub, reviewed the license, and even reached out to the author. You're feeling great about your decision.
You begin to write your mission-critical code, and you realize there is a bug. This bug is easily fixable, but what do you do?
Solutions To Solving Your Bug
When using OSS today, you have several options to resolve your issue. They range in trade-offs in time to sacrificing community credibility. Let me explain what they are.
The Righteous Solution
With today's .NET, you have one reasonable option.
- You fork the author's code on GitHub
- Create a patch / pull-request with the necessary changes
- Wait for the PR to be merged
- Wait for the Nuget package to be updated
If all goes well, you should have a fix in a day or so, and you can continue. If it doesn't, you're pull-request sits in an author's repository gathering digital dust.
The Tedious Solution
If you are an impatient individual and let's admit it, we all can be at times; you'll do the following:
- You fork the author's code
- Fix the bug
- Compile the fix to a local assembly
- Use your compiled copy
You've identified a bug, but that fix never makes it upstream. You also now maintain a duplicate of the author's project with the inability to get other fixes and changes.
The Counter-productive Solution
This is the most extreme of all solutions and is not recommended:
- You fork the author's code
- Create a duplicate project
- Push your duplicate project to Nuget
- Claim the author's project is dead and you are its savior
The approach described above is a ludicrous option, but if you are an OSS author, you know this is too common a scenario. Again, don't do this.
Why Monkey Patching is essential for .NET right now
In the last two years, we've seen .NET Core released and developed in the open. Not only have we witnessed Microsoft shift towards open source software (OSS), but the gravity is pulling more developers in the .NET ecosystem to embrace solution developed in the open.
My main argument for monkey patching is to help drive adoption of OSS while keeping developers productive and alleviating pressure on OSS maintainers.
How would monkey patching do that?
Advantages To Monkey Patching In .NET
Monkey patching would bring the following advantages to the .NET Ecosystem:
Increased Adoption
Adoption of OSS libraries would grow because developers would feel more comfortable adopting dependencies they knew they could fix promptly.
GitHub and social platforms have made it easier to see what issues there are and to contribute fixes. That said, turn around time varies from project to project. Monkey patching removes that uncertainty developers may feel about resolving their block issues.
Less Duplication
In .NET, most projects are duplicated because the community feels the project is "dead." The project may not be dead, and inactivity could be attributed to a plethora of reasons.
With monkey patching, the community could continue to use a solution and make the necessary changes around bugs without duplicating an authors project.
As good community members, we would submit the pull requests but not feel the need to pressure the author to merge our work.
Reduce Stress on OSS Authors
It is stressful maintaining an OSS project, as proved by a simple Google search. By introducing monkey patching, we give authors more time to review and accept pull-requests. Monkey patching introduces a healthier OSS-life balance and leads to longer-lived projects.
Where Do We Start With Monkey Patching
It's possible to do some Monkey Patching in .NET today, but it would require reflection and ultimately be difficult to maintain. What .NET needs is first class support for the concept in the C# language.
I believe a patch
keyword interpreted by the compiler would be the best way of supporting monkey patching.
namespace InAnotherAssembly
{
public class BadLogic {
public bool IsValid () {
return 1 == 2;
}
}
}
namespace MyAssembly {
public class BadLogic
patch InAnotherAssembly.BadLogic
{
public override bool IsValid () {
return 1 == 1;
}
}
}
By supporting a first class patch
keyword, it will be easier for developers to fix buggy dependencies. We also get the added benefit of easier unit testing since we can stub behavior.
The Monkey Patch Solution
I had examples of procedures to follow when attempting to fix bugs in a dependency. The introduction of monkey patching introduces a new approach:
- You create a patch in your code and confirm the fix
- You fork the author's code on GitHub
- Create a patch / pull-request with the necessary changes
- Wait for the PR to be merged
- Wait for the Nuget package to be updated
- Remove the patch from your code when necessary
During the time the author is reviewing your code, we can continue being productive and shipping. We also respected the OSS ecosystem that is helping you be productive. At no time do we have to think about duplicating the project, harassing the author, or swearing off OSS altogether.
Conclusion
We are in the era of OSS software. To continue to see its adoption we need more tools that help us be productive. Productivity means reducing the time it takes between finding bugs and fixing them. In a distributed ecosystem, monkey patching is a powerful way to help sustain the positive momentum we have generated.
I'd like to hear your thoughts, and if you are a polyglot developer using a dynamic language how you've used monkey patching (if ever).