Skip to content

Commit b5a115c

Browse files
author
Greg Domzalski
committed
Add appcompat doc in user's manual
1 parent bd152b4 commit b5a115c

File tree

2 files changed

+107
-0
lines changed

2 files changed

+107
-0
lines changed

Yubico.NET.SDK.sln

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Sdk Programming Guide", "Sd
178178
Yubico.YubiKey\docs\users-manual\sdk-programming-guide\secure-channel-protocol-3.md = Yubico.YubiKey\docs\users-manual\sdk-programming-guide\secure-channel-protocol-3.md
179179
Yubico.YubiKey\docs\users-manual\sdk-programming-guide\sensitive-data.md = Yubico.YubiKey\docs\users-manual\sdk-programming-guide\sensitive-data.md
180180
Yubico.YubiKey\docs\users-manual\sdk-programming-guide\threads.md = Yubico.YubiKey\docs\users-manual\sdk-programming-guide\threads.md
181+
Yubico.YubiKey\docs\users-manual\sdk-programming-guide\appcompat.md = Yubico.YubiKey\docs\users-manual\sdk-programming-guide\appcompat.md
181182
EndProjectSection
182183
EndProject
183184
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Apdu", "Apdu", "{BA394A0D-B336-4B6E-83B8-B41FC165D6D9}"
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
---
2+
uid: AppCompat
3+
---
4+
5+
<!-- Copyright 2024 Yubico AB
6+
7+
Licensed under the Apache License, Version 2.0 (the "License");
8+
you may not use this file except in compliance with the License.
9+
You may obtain a copy of the License at
10+
11+
http://www.apache.org/licenses/LICENSE-2.0
12+
13+
Unless required by applicable law or agreed to in writing, software
14+
distributed under the License is distributed on an "AS IS" BASIS,
15+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
See the License for the specific language governing permissions and
17+
limitations under the License. -->
18+
19+
# Maintaining compatibility
20+
21+
This article describes the various decisions that the SDK makes in order to maintain application and source
22+
compatibility across our versions.
23+
24+
## App-compat strategy for this SDK
25+
26+
The .NET SDK strives to maintain both source and behavioral compatibility across its releases.
27+
28+
**Source compatibility** is the promise that your source code should continue to compile as-is when you update your
29+
application to the latest version of the SDK. This promise extends to "minor" (feature) and "patch" (bug-fix) releases
30+
of the SDK. Additionally, we only make this guarantee for the `Yubico.YubiKey` and the `Yubico.Core` assemblies. Since
31+
`Yubico.NativeShims` and `Yubico.DotnetPolyfills` are meant to be purely for internal use, we *do not* make any
32+
guarantees here.
33+
34+
**Behavioral compatibility** is the promise that your application will behave exactly the same after you have upgraded
35+
the YubiKey SDK version. Maintaining this guarantee is far more difficult and is sometimes simply not possible. However,
36+
we will continue to do our best to maintain behavioral stability across releases. If a behavioral change is
37+
necessitated, such as fixing a bug, we may choose to simply fix the issue. This is far more likely to occur if the bug
38+
prevented the feature from ever working in the first place and no workaround was present. If the change is more nuanced
39+
than that, or it is changing behavior for some other reason, we have a separate mechanism that we've started using so
40+
that these behavior changes may be managed through an opt-in or opt-out decision.
41+
42+
There are two exceptions to these promises:
43+
44+
1. Sometimes a breaking change is unavoidable. Perhaps a new YubiKey feature was released that is simply impossible to
45+
express with the existing shape of the API. Or a bug was discovered, and it simply must be addressed. In these cases,
46+
we will do everything in our power to first mark the affected types or members with the `ObsoleteAttribute` so that
47+
you are alerted the fact that there's an issue with the old usage. The attribute will contain text that will result
48+
in a usage warning when you recompile. This text will be included in the warning message and will point you to the
49+
new API that should be used instead. The old API will remain for several minor releases before we consider it safe to
50+
remove entirely. A major release would remove all obsolete APIs in one go.
51+
52+
2. You will note that the promise is only made for minor and patch releases. For example, upgrading feature releases
53+
(i.e. `1.9.1` to `1.10.0`) or upgrading patch releases (i.e. `1.9.0` to `1.9.1`) have this guarantee. What has been
54+
omitted here is "major" releases (i.e. `1.10.0` to `2.0.0`). Major version releases are our chance to make broader
55+
changes that address design-level issues. It should be expected that there will be source level breaking changes when
56+
a major version is released.
57+
58+
Our SDK does *not* make any promises around **Application Binary Interface (ABI)** stability. This expectation is
59+
generally far less common in the .NET ecosystem to begin with, however there are two very important implications here:
60+
61+
1. You *must* recompile your code against a new version of our SDK. Simply replacing our assemblies with a newer version
62+
is **not** supported and could result in undefined behavior and bugs in your application's behavior.
63+
64+
2. If an enumeration does not have an explicitly defined value, you should assume that the underlying value may change.
65+
While these changes should not result in any changes to behavior (assuming you've recompiled) it does mean that these
66+
values should not be serialized and stored across versions. If you need to persist these values for whatever reason,
67+
it is strongly recommended you create your own stable values to map to, or use another mechanism that does not depend
68+
on the specific compiler-generated enumeration value.
69+
70+
## Managing behavior changes through app-compat switches
71+
72+
Sometimes it's unavoidable that the SDK must make a behavior breaking change. For example: a bug has been addressed that
73+
causes subtle behavior changes that have existed for many releases. Or perhaps an optimization has been made that may
74+
result in different timings that could have an effect on UI applications.
75+
76+
In these cases, we've introduced a new mechanism for adjusting these behaviors through the use of app-compat switches.
77+
These switches use the
78+
[`AppContext.SetSwitch`](https://learn.microsoft.com/en-us/dotnet/api/system.appcontext.setswitch) mechanism exposed by
79+
the .NET Base Class Library.
80+
81+
Whether a behavior change is opt-in or opt-out will be decided on a case-by-case basis. Generally, if we view the change
82+
to be a net positive and have a low risk of observable changes to an application, we will make the change opt-out. That
83+
means, you will get the new behavior by default. Only if the change causes your application problems should you consider
84+
setting the switch to disable that behavior.
85+
86+
For more observable or impactful changes, or changes that would benefit a smaller subset of consumers, we will make the
87+
change opt-in. That is, the existing behaviors will be maintained, and your application must explicitly call `SetSwitch`
88+
with a value of `true`.
89+
90+
This decision is clearly very subjective. Any time a behavior change is made, there is a high likelihood that at least
91+
one consumer will be adversely affected no matter which behavior we choose. That's why we've introduced these switches
92+
in the first place. There will always be a case where someone will need to override out decision. This is your mechanism
93+
to do so.
94+
95+
All of our compatibility switch names are defined in two central classes:
96+
97+
- [YubiKeyCompatSwitches](xref:Yubico.YubiKey.YubiKeyCompatSwitches) - This class holds all the compatibility switches
98+
that affect the behaviors of the `Yubico.YubiKey` assembly.
99+
- [CoreCompatSwitches](xref:Yubico.Core.CoreCompatSwitches) - This class holds all the compatibility switches that
100+
affect the `Yubico.Core` assembly. `Yubico.Core` serves as our platform abstraction layer, so switches here may only
101+
impact a certain operating system or a certain downstream dependency. While not YubiKey specific, it may affect things
102+
like enumeration and eventing of YubiKeys.
103+
104+
Each flag will have a clear explanation of what behavior it affects, what the default is, and what the impact of
105+
overriding the default should be. Use these constants as the value for the `switchName` parameter of
106+
`AppContext.SetSwitch`.

0 commit comments

Comments
 (0)