Updating my .NET packages
Back in 2013, I released my MarkEmbling.Utils package containing a bunch of extension methods, helpers and so on which I often re-use across various projects. Since then, a lot has changed in the .NET world and the time has come for me to revisit this package, giving it some much-needed attention and correcting a few decisions which in hindsight were not the best choices.
Recently I started working on a .NET Core port of a website which was previously built using ASP.NET MVC 5. Part of this process was making sure the new .NET Core version referenced all the necessary packages which the site depended on, and one of these was MarkEmbling.Utils. I immediately hit a problem in that a .NET Core application could not reference a library built for .NET 4.0.
Since I knew I had to update this package, I wanted to address all the issues which I had with it in one go - and making the library .NET Core compatible would certainly force the issue with some of this:
- The package contained a variety of different and disparate features, some of which didn't necessarily belong together in one place and came with their own dependencies and/or platform requirements
- .NET Framework targeting - .NET Core apps could not take a dependency on the library.
I decided to address these issues and concerns by making a series of decisions which I'll explain here.
A new name
I've not been a fan of 'Utils' for some time so I decided to move it over to MarkEmbling.Utilities. I'm not sure why I went with that originally but I guess it seemed like a good idea at the time. I'm aware that doing things like this can upset people as it can easily be argued it's just a change for the sake of it. However it's not something that's used heavily and sorry but it's my package and my decision - I feel it's justified.
A negative of changing the name like this is that NuGet doesn't really have a story for marking a package as deprecated or obsolete, or for indicating that a package replaces another. That means it's now possible to install both the old one and the new one (side by side in the same project, potentially) and any projects currently using the old package will get no indication that they can or should update. It definitely increases confusion but also retains the history and backwards compatibility as projects relying on the old package won't be affected, so it's a compromise I'm happy to live with going forwards.
Regarding version numbers, I'm now thankful that I never incremented the version number for the old MarkEmbling.Utils package beyond the 0.x series so starting the versioning for MarkEmbling.Utilities at 1.x makes sense however you choose to look at the situation.
Remove features relying on interop
There were one or two features which relied on platform-specific interop. This is definitely not cross-platform and has no place in a library which I'd like to keep platform-neutral. I've removed it entirely and it likely won't be coming back anywhere - definitely not in this package at least. I won't rule out other platform-specific packages which hold anything like that but I'm not convinced there's any value in doing it.
Split out grammar features
The grammar features such as pluralisation and so on which all lived in the
MarkEmbling.Utils.Grammar namespace are all gone. In my mind, they're a distinct enough feature-set that they deserve to be in their own package which can then be used separately.
Because of this, I've taken it all out of the MarkEmbling.Utilities package and it is now found in MarkEmbling.Grammar where it'll be developed and maintained. I'll be releasing this package to NuGet in the near future once I've finished porting it all over and am happy it's ready to go. Again, this is another breaking change which isn't easy to communicate, but again I feel it's the right decision.
Remove Windows Forms features
The Windows Forms stuff previously in
MarkEmbling.Utils.Forms had to go. Since it's specific to Windows Forms, it needs to remain a .NET Framework package and whilst I could have left it in the solution, that definitely didn't feel like the right thing to do. For now, it's removed entirely.
I haven't yet decided what I'll do with it but again, the existing NuGet package remains available for use.
Move to .NET Standard
This was one of the main changes I needed to make to ensure the libraries are usable from .NET Core. Right now, the MarkEmbling.Utilities and MarkEmbling.Grammar packages both target .NET Standard 1.1. Looking at the compatibility grid, this means it'll be usable from .NET Core 1.0 and .NET Framework 4.5, amongst others. As time goes on, this may move to later versions as new .NET APIs dictate the need.
Going forward, I intend on making sure any new libraries I create for .NET target an appropriate .NET Standard version. This keeps them as portable as possible, ensuring they can be used from any .NET platform. Given a bit of time, I hope to port over other .NET libraries such as MarkEmbling.PostcodesIO to .NET standard too.
Regarding random name changes and reorganisations - this is something I'd like to keep to a minimum from now on. I decided to do it this time as I was making a bunch of changes and if any time was the right time, it was this time but as I said before, it isn't ideal. I'm under no illusions that I'm building anything groundbreaking or important here, so in reality this is probably affecting a very small number of people, but the principle still stands. But where else better to experiment on, right?
It's an exciting time in the .NET space now, with the advent of .NET Core and .NET Standard, and I'm excited to be able to embrace it and participate in the ecosystem. Feel free to take a look at the things I'm building over on GitHub and my packages on NuGet and hopefully they might be useful to you.