A breaking change regarding IShippingPlugin/IShippingGateway in Commerce 12
As you might already know, we reserve the major versions for breaking changes - when you upgrade to a major version, expect to have to change your code to make it compile and work.
Our latest major version is Commerce 12, which was released almost two months ago, and the full list of breaking changes can be seen here https://world.episerver.com/documentation/upgrading/episerver-commerce/commerce-12/breaking-changes-commerce-12/
However one breaking change is easier to miss than the other, that's why I think it should get more attention.
If you only fix your code to build, then when you run it, you will likely run into this exception
<Your super cool shipping gateway> does not implement IShippingPlugin nor IShippingGateway.
Why is that and how to fix it?
In a Commerce implementation you might have multiple gateways, for example free shipping for customers who can wait and express shipping for ones who can't. For each and every shipment you would need to get the gateway assigned to it and use it to calculate the shipping rate. Previously, the instance of the shipping gateway is created by Activator, and it requires the implementation to have a constructor which takes an IMarket parameter. That is quite obsecure and hard to know before hand. Also if you are a seasoned Episerver developer, you might be like "Activator, seriously?". Well, those code are probably one of the oldest parts in our repository, so it's less "modern".
In Commerce 12 we changed the way to get the implementation of a shipping gateway (and a minor change to the signature of the interfaces themselves. Now you need to pass an IMarket to the method, not to create a constructor which takes one. In fact, you must remove that constructor because there is no default implementation registered for IMarket). And you might have guess it - via dependency injection. We now rely on the Inversion of control framework to give us an implementation of the shipping gateway being used. While that gives us much more flexibility, it also comes at a cost: because the shipping gateways are implementations of IShippingPlugin or IShippingGateway, or both, the IoC framework can't just detect it, unless you register specifically.
So the only extra work you need is to add this attribute to your implementation
[ServiceConfiguration(ServiceType = typeof(IShippingPlugin))]
[ServiceConfiguration(ServiceType = typeof(IShippingGateway))]
And that's it. Your shipping gateways are now ready!