Upgrading a 3.7 pipeline extension to 3.8, some issues

Hello,

nice release you got there :slight_smile: :+1:

I was wondering what would be the way to upgrade a content pipeline extension currently using :

  • net471
  • Monogame.Framework.Content.Pipeline.Portable 3.7 package

For now, I tried recompiling the extension with ;

  • netcoreapp3.1
  • removed Monogame.Framework.Content.Pipeline.Portable 3.7 package
  • added Monogame.Framework.Content.Pipeline 3.8 package
  • added Monogame.Framework.DesktopGL 3.8 package

Compiling looks ok even if i feel that the portable package was way nicer for pipeline extensions.

The problem is that when using this extension in the new mgcb-editor, i have an exception :
Could not load file or assembly ‘System.Drawing.Common, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51’. File not found.

So, I’m not sure to have taken the right path here, any suggestions ?

( fyi, the extension is just a texture atlas creator )

I believe this is an issue with changing your target framework from net471 to netcoreapp3.1, not anything to do with MonoGame. System.Drawing.Common isn’t support in .NET Core without the Microsoft.Windows.Compatibility package (see the announcement or a StackOverflow answer). But if net471 was working for you, I think you can go back to that because Content.Pipeline and DesktopGL are both netstandard2.0, which is compatible with net471.

Of course if you want your extension to work smoothly cross-platform, the best option might be to consider an alternate drawing package. But if you always build on Windows, that’s not a big concern.

1 Like

Thanks for your answer.

The extension is indeed using Microsoft.Windows.Compatibility package, I did not mention it, sorry :bowing_man:
I’ll consider your advice of changing the drawing library. Thanks.

So, that being said, I still have trouble making some sense out of this issue, and probably because i’m lacking some knowledge about the whole .net universe.

If i want to create a cross-platform pipeline extension for the 3.8 pipeline :

  • what are the needed packages to reference ContentImporter / ContentProcessor / ContentWriter ?
  • what are the target frameworks that are supported ? ( I know you already kind of answered that, but maybe there’s more to say about it )

Thanks in advance.

tl;dr You can see the example in the template.


So the questions of making a pipeline extension and making it cross-platform are actually somewhat independent.

For a 3.8 pipeline extension, you actually have it right:

  • Change Monogame.Framework.Content.Pipeline.Portable 3.7 to Monogame.Framework.Content.Pipeline 3.8
  • Reference Monogame.Framework.DesktopGL because in a way it’s the most neutral platform

Now for making it cross-platform. So there are a few things to know about .NET:

  • .NET Framework
    • Generally targeted at Windows
    • But can be made to run cross-platform with things like Mono (a cross-platform .NET Framework port) and Wine (a Windows compatibility layer for Linux).
  • .NET Core
    • Generally cross-platform
    • But can end up only running on Windows if you use some of the Windows-specific SDKs like WPF, Windows Forms, or Microsoft.Windows.Compatibility. Despite breaking the cross-platform intent of .NET Core, these were added to allow Windows developers to take advantage of the great new .NET Core features and convenience.
  • .NET Standard
    • A cross-platform standard (or set of APIs) that a library can target if it’s not to be run as a standalone app
    • Doesn’t contain the platform-specific implementation, so they don’t really know how to run themselves. .NET Core and .NET Framework implement the standard, meaning if your library says to “make an HTTP request” then when a .NET Core App uses the library, it knows how to do that on the platform it’s running, and when a .NET Framework app uses the library, it knows how to do that on Windows.

So if you want something to be cross-platform, you generally want to use .NET Standard if it’s a library, and .NET Core App if it’s an app. For a content pipeline extension, it doesn’t run itself but is instead loaded by MGCB, so the best option is to target netstandard2.0.

As for what options are supported, Monogame.Framework.Content.Pipeline is netstandard2.0 so you can use that .NET Standard or higher, or any .NET Core or .NET Framework version that implements that .NET Standard or higher (which again you can find in this link, but that’s netcoreapp2.0+ or net461+).

1 Like

Thanks a lot, very helpful and informative.

I migrated this extension to netstandard2.0.
I replaced the drawing library with ImageSharp.

The only part where I scratched a bit my head was that I had to provide the ImageSharp dll quite manually to the mgcb-editor.

Again, thanks for your patience and your explanations :bowing_man:

1 Like

No problem at all :slightly_smiling_face:

I don’t entirely remember how referencing the extension works from the mgcb file, but since it loads with the assembly and uses reflection at runtime, it’s possible that since your extension has dependencies, you would have to specify any of those in the mgcb as well.

You might be able to do something funky where you publish your extension as a single file netcoreapp and then only need to reference the one file since it would pack ImageSharp along with your code, but I don’t think anyone’s tried that so it would be experimental.

1 Like