Update: 2023-05-23. Due to the lack of interest, the Umbraco Polyfill package has now been deprecated. The source code is available on GitHub: https://github.com/leekelleher/umbraco-polyfill
If you are unfamiliar with the term polyfill in web development, here is the definition from MDN...
A polyfill is a piece of code (usually JavaScript on the Web) used to provide modern functionality on older browsers that do not natively support it.
https://developer.mozilla.org/en-US/docs/Glossary/Polyfill
Typically, polyfills are referenced in the context of front-end web development, but they could also be applied to server-side APIs.
I hear you asking: What does this have to do with Umbraco packages?
This time last year, I'd started migrating my Umbraco package, Contentment to support Umbraco 9 on ASP.NET Core 5. My initial approach was to drop support for Umbraco 8 to focus exclusively on Umbraco 9. A decision that niggled me.
During the code migration, I'd discussed with fellow Umbraco package developers about multi-targeting .NET frameworks within the same codebase, and indeed it was possible, meaning that Contentment could still support Umbraco 8. The downsize would be that there would be many #if
/#else
pre-processor directives littered throughout the codebase.
For more details on this approach, take a read of
the Package Migration to V9 Using Multi-Targeting post on the Umbraco blog.
#if NET
private readonly ILogger<MyClass> _logger;
public MyClass(ILogger<MyClass> logger)
{
_logger = logger;
}
#else
private readonly ILogger _logger;
public MyClass(ILogger logger)
{
_logger = logger;
}
#endif
public void MyMethod()
{
// Do some common logic and log a result
var result = "Some value";
#if NET
_logger.Debug(result);
#else
_logger.Debug<MyClass>(result);
#endif
}
Code snippet taken from @mattbrailsford's Adding
ILogger<T>
support to Umbraco v8 post.
Whilst I really liked the idea of multi-targeting, the amount of pre-processor directives did start to get silly. I wondered why that was and what could be done about it.
Of course, the API between Umbraco 8 and 9 were different, some changes were subtle, others breaking. All for understandable reasons.
With Contentment, one of the more common bits was that the IOHelper.ResolveUrl()
was no longer a static method, and a new IIOHelper
instance would need to be injected, meaning adding an extra parameter to the class constructor.
Since IIOHelper
wasn't available in Umbraco 8, I ended up using conditional pre-processor directives...
#if NET472
public DropdownListDataListEditor()
{
}
#else
private readonly IIOHelper _ioHelper;
public DropdownListDataListEditor(IIOHelper ioHelper)
{
_ioHelper = ioHelper;
}
#endif
...and this happened in a lot of places!
My thinking was that I could introduce a polyfill for IIOHelper
in Umbraco 8 only. (Given the v8 roadmap, I doubted that it would ever be added to v8.x patch release.) So that's what I did, here's a link to the code for the IIOHelper
polyfill and how it is registered using dependency injection in a Composer.
Now my code would look like this...
private readonly IIOHelper _ioHelper;
public DropdownListDataListEditor(IIOHelper ioHelper)
{
_ioHelper = ioHelper;
}
Removing the need for the conditional pre-processor directives, and maintaining the same functionality and logic.
Taking this approach to some of the other v9-only interfaces and services, I was able to reduce the verbosity of Contentment's codebase. You can see the other polyfill code on the GitHub repository.
Okay, now what?
This was all great for my Contentment package, happy days. Until when I started developing a new Umbraco package. I developed the code against Umbraco 9, but when I reviewed the code I could see the potential of adding support for Umbraco 8 with a few conditional pre-processor directives. So I copied the polyfill code over from Contentment... wait a minute, what am I doing?
At this point I separated out the polyfill code to its own code library, so that it could be referenced in my other (future) Umbraco packages.
https://github.com/leekelleher/umbraco-polyfill
...and released a NuGet package:
https://www.nuget.org/packages/Our.Umbraco.Community.Polyfill/
Just to note, in it's current release, this library should be considered a continued work-in-progress, and NOT feature complete. If you are a package developer and find there are missing features, I'm happy to collaborate with you on the GitHub repository.
Top comments (0)