One of the primary considerations when building a software platform that other developers based their work on is to maintain backwards compatibility. As the platform grows larger and more complex, this can become the major restraining factor when trying to sustain a high development pace.
Using strict semantic versioning, it becomes obvious that no API changes can be done no matter how small the change or how obscure the class is, unless releasing a new major version. And while releasing a new major version might not be as big a deal as it used to be, it does add additional work, not just internally, but also for maintainers of third-party modules trying to keep their modules up-to-date.
The typical approach to this problem is to keep your public classes to a minimum and only expose classes that are actually useful to interact with for external developers. Limiting the API is currently done primarily by keeping classes or methods internal.
One way of doing that is by adding the internal keyword to a class, but this is not always the preferred way by users. Another option is to use the API documentation and explicitly call out the classes and methods that are considered internal. However, this has the drawback that it can sometimes be hard to keep track of which APIs are public or not if they are spread out.
A third way, sometimes refered to as "pubternal" or "internal namespaces", consists of using a specific namespace pattern to indicate that you are now dealing with classes that are not a part of the public API. Previously, Optimizely used the first two options, but from 2016 we have been using the internal namespaces option.
This means that any class located in a namespace named Internal is not considered a part of our supported public API. Such classes can still be used, but they are not covered by the semantic versioning promise and can therefore change between minor releases without prior warning. Any problems that arise from using such classes are also not covered by our usual support.
It does, however, mean that we can expose more classes as public in our assemblies so that they are easier to use if you really, really need to or for any non-production scenarios such as for unit testing.
This does not imply that everything outside these namespaces is a part of the public API as there are still classes and methods that are explicitly documented as being for “internal use” but these are kept to a minimal whenever possible.
In the first major release after we started using internal namespaces, Optimizely CMS 10, a lot of classes where moved from their previous location to Internal namespaces. This included any classes not considered important for typical use cases or implementations of public abstractions. So when you upgrade a pre-version 10 solution, please be careful and make sure that you do not accidentally add any Internal namespaces to your using statements as this may cause you problems in the future.
Updated 4 months ago