Releases: launchdarkly/dotnet-client-sdk
3.0.0
[3.0.0] - 2022-12-21
The latest version of this SDK supports LaunchDarkly's new custom contexts feature. Contexts are an evolution of a previously-existing concept, "users." Contexts let you create targeting rules for feature flags based on a variety of different information, including attributes pertaining to users, organizations, devices, and more. You can even combine contexts to create "multi-contexts."
This feature is only available to members of LaunchDarkly's Early Access Program (EAP). If you're in the EAP, you can use contexts by updating your SDK to the latest version and, if applicable, updating your Relay Proxy. Outdated SDK versions do not support contexts, and will cause unpredictable flag evaluation behavior.
If you are not in the EAP, only use single contexts of kind "user", or continue to use the user type if available. If you try to create contexts, the context will be sent to LaunchDarkly, but any data not related to the user object will be ignored.
For detailed information about this version, please refer to the list below. For information on how to upgrade from the previous version, please read the migration guide.
Added:
- In
LaunchDarkly.Sdk
, the typesContext
andContextKind
define the new context model. - For all SDK methods that took a
User
parameter, there is now a method that takes aContext
. The correspondingUser
methods are defined as extension methods. The SDK still supportsUser
for now, butContext
is the preferred model andUser
may be removed in a future version. ConfigurationBuilder.GenerateAnonymousKeys
is the new way of enabling the "generate a key for anonymous users" behavior that was previously enabled by setting the user key to null. If you setGenerateAnonymousKeys
totrue
, all anonymous contexts will have their keys replaced by generated keys; if you do not set it, anonymous contexts will keep whatever placeholder keys you gave them.- The
TestData
flag builder methods have been extended to support now context-related options, such as matching a key for a specific context type other than "user". LdClient.FlushAndWait()
andFlushAndWaitAsync()
are equivalent toFlush()
but will wait for the events to actually be delivered.
Changed (breaking changes from 2.x):
- It was previously allowable to set a user key to an empty string. In the new context model, the key is not allowed to be empty. Trying to use an empty key will cause evaluations to fail and return the default value.
- There is no longer such a thing as a
Secondary
meta-attribute that affects percentage rollouts. If you set an attribute with that name in aContext
, it will simply be a custom attribute like any other. - The
Anonymous
attribute inUser
is now a simple boolean, with no distinction between a false state and a null state. - Types such as
IPersistentDataStore
, which define the low-level interfaces of LaunchDarkly SDK components and allow implementation of custom components, have been moved out of theInterfaces
namespace into a newSubsystems
namespace. Application code normally does not refer to these types except possibly to hold a value for a configuration property such asConfigurationBuilder.DataStore
, so this change is likely to only affect configuration-related logic.
Changed (behavioral changes):
- Analytics event data now uses a new JSON schema due to differences between the context model and the old user model.
- The SDK no longer adds
device
andos
values to the user attributes. Applications that wish to use device/OS information in feature flag rules must explicitly add such information.
Changed (requirements/dependencies/build):
- There is no longer a dependency on
LaunchDarkly.JsonStream
. This package existed because some platforms did not support theSystem.Text.Json
API, but that is no longer the case and the SDK now usesSystem.Text.Json
directly for all of its JSON operations. - If you are using the package
LaunchDarkly.CommonSdk.JsonNet
for interoperability with the Json.NET library, you must update this to the latest major version.
Removed:
- Removed all types, fields, and methods that were deprecated as of the most recent 2.x release.
- Removed the
Secondary
meta-attribute inUser
andUserBuilder
. - The
Alias
method no longer exists because alias events are not needed in the new context model. - The
AutoAliasingOptOut
andInlineUsersInEvents
options no longer exist because they are not relevant in the new context model. LaunchDarkly.Sdk.Json.JsonException
: this type is no longer necessary because the SDK now always usesSystem.Text.Json
, so any error when deserializing an object from JSON will throw aSystem.Text.Json.JsonException
.
2.0.2
[2.0.2] - 2022-11-28
Fixed:
- One of the SDK's dependencies,
LaunchDarkly.Logging
, had an Authenticode signature without a timestamp. The dependency has been updated to a new version with a valid signature. There are no other changes.
2.0.1
[2.0.1] - 2022-02-08
Fixed:
- Analytics events generated by
LdClient.Alias
did not have correct timestamps, although this was unlikely to affect how LaunchDarkly processed them. - The type
LaunchDarkly.Sdk.UnixMillisecondTime
now serializes and deserializes correctly withSystem.Text.Json
.
2.0.0
[2.0.0] - 2022-01-07
This is a major rewrite that introduces a cleaner API design, adds new features, and makes the SDK code easier to maintain and extend. See the Xamarin 1.x to client-side .NET 2.0 migration guide for an in-depth look at the changes in 2.0; the following is a summary.
The LaunchDarkly client-side .NET SDK was formerly known as the LaunchDarkly Xamarin SDK. Xamarin for Android and iOS are among its supported platforms, but it can also be used on any platform that supports .NET Core 2+, .NET Standard 2, or .NET 5+. On those platforms, it does not use any Xamarin-specific runtime libraries. To learn more about the distinction between the client-side .NET SDK and the server-side .NET SDK, read: Client-side and server-side SDKs
Added:
LdClient.FlagTracker
provides the ability to get notifications when flag values have changed.LdClient.DataSourceStatusProvider
provides information on the status of the SDK's data source (which normally means the streaming connection to the LaunchDarkly service).LdClient.DoubleVariation
andDoubleVariationDetail
return a numeric flag variation using double-precision floating-point.ConfigurationBuilder.ServiceEndpoints
allows you to override the regular service URIs— as you may want to do if you are using the LaunchDarkly Relay Proxy, for instance— in a single place. Previously, the URIs had to be specified individually for each service (StreamingDataSource().BaseURI
,SendEvents().BaseURI
, etc.).HttpConfigurationBuilder.UseReport
tells the SDK to make HTTPREPORT
requests rather thanGET
requests to the LaunchDarkly service endpoints, which may be desirable in rare circumstances but is not available on all platforms.ConfigurationBuilder.Persistence
andPersistenceConfigurationBuilder.MaxCachedUsers
allow setting a limit on how many users' flag data can be saved in persistent local storage, or turning off persistence.- The
LaunchDarkly.Sdk.Json
namespace provides methods for converting types likeUser
andFeatureFlagsState
to and from JSON. - The
LaunchDarkly.Sdk.UserAttribute
type provides a less error-prone way to refer to user attribute names in configuration, and can also be used to get an arbitrary attribute from a user. - The
LaunchDarkly.Sdk.UnixMillisecondTime
type provides convenience methods for converting to and from the Unix epoch millisecond time format that LaunchDarkly uses for all timestamp values. - The SDK now periodically sends diagnostic data to LaunchDarkly, describing the version and configuration of the SDK, the architecture and version of the runtime platform, and performance statistics. No credentials, hostnames, or other identifiable values are included. This behavior can be disabled with
ConfigurationBuilder.DiagnosticOptOut
or configured withConfigurationBuilder.DiagnosticRecordingInterval
.
Changed (requirements/dependencies/build):
- .NET Standard 1.6 is no longer supported.
- The SDK no longer has a dependency on
Common.Logging
. Instead, it uses a similar but simpler logging facade, theLaunchDarkly.Logging
package, which has adapters for various logging destinations. - The SDK no longer has a dependency on the Json.NET library (a.k.a.
Newtonsoft.Json
), but instead uses a lightweight custom JSON serializer and deserializer. This removes the potential for dependency version conflicts in applications that use Json.NET for their own purposes, and reduces the number of dependencies in applications that do not use Json.NET. If you do use Json.NET and you want to use it with SDK data types likeUser
andLdValue
, seeLaunchDarkly.CommonSdk.JsonNet
. Those types also serialize/deserialize correctly with theSystem.Text.Json
API on platforms where that API is available.
Changed (API changes):
- The base namespace has changed: types that were previously in
LaunchDarkly.Client
are now inLaunchDarkly.Sdk
, and types that were previously inLaunchDarkly.Xamarin
are now inLaunchDarkly.Sdk.Client
. TheLaunchDarkly.Sdk
namespace contains types that are not specific to the client-side .NET SDK (that is, they are also used by the server-side .NET SDK):EvaluationDetail
,LdValue
,User
, andUserBuilder
. Types that are specific to the client-side .NET SDK, such asConfiguration
andLdClient
, are inLaunchDarkly.Sdk.Client
. User
andConfiguration
objects are now immutable. To specify properties for these classes, you must now useUser.Builder
andConfiguration.Builder
.Configuration.Builder
now returns a concrete type rather than an interface.EvaluationDetail
is now a struct type rather than a class.EvaluationReason
is now a single struct type rather than a base class with subclasses.EvaluationReasonKind
andEvaluationErrorKind
constants now use .Net-style naming (RuleMatch
) rather than Java-style naming (RULE_MATCH
). Their JSON representations are unchanged.- The
ILdClient
interface is now inLaunchDarkly.Sdk.Client.Interfaces
instead of the main namespace. - The
ILdClientExtensions
methodsEnumVariation<T>
andEnumVariationDetail<T>
now have type constraints to enforce thatT
really is anenum
type.
Changed (behavioral changes):
- The default event flush interval is now 30 seconds on mobile platforms, instead of 5 seconds. This is consistent with the other mobile SDKs and is intended to reduce network traffic.
- Logging now uses a simpler, more stable set of logger names instead of using the names of specific implementation classes that are subject to change. General messages are logged under
LaunchDarkly.Sdk
, while messages about specific areas of functionality are logged under that name plus.DataSource
(streaming, polling, file data, etc.),.DataStore
(database integrations),.Evaluation
(unexpected errors during flag evaluations), or.Events
(analytics event processing).
Removed:
- All types and methods that were deprecated as of the last 1.x release have been removed.
2.0.0-rc.1
[2.0.0-rc.1] - 2021-11-19
This is the first release candidate version of the LaunchDarkly client-side .NET SDK 2.0-- a major rewrite that introduces a cleaner API design, adds new features, and makes the SDK code easier to maintain and extend. See the Xamarin 1.x to client-side .NET 2.0 migration guide for an in-depth look at the changes in 2.0; the following is a summary.
The LaunchDarkly client-side .NET SDK was formerly known as the LaunchDarkly Xamarin SDK. Xamarin for Android and iOS are among its supported platforms, but it can also be used on any platform that supports .NET Core 2+, .NET Standard 2, or .NET 5+. On those platforms, it does not use any Xamarin-specific runtime libraries. To learn more about the distinction between the client-side .NET SDK and the server-side .NET SDK, read: Client-side and server-side SDKs
Added:
LdClient.FlagTracker
provides the ability to get notifications when flag values have changed.LdClient.DataSourceStatusProvider
provides information on the status of the SDK's data source (which normally means the streaming connection to the LaunchDarkly service).LdClient.DoubleVariation
andDoubleVariationDetail
return a numeric flag variation using double-precision floating-point.HttpConfigurationBuilder.UseReport
tells the SDK to make HTTPREPORT
requests rather thanGET
requests to the LaunchDarkly service endpoints, which may be desirable in rare circumstances but is not available on all platforms.ConfigurationBuilder.Persistence
andPersistenceConfigurationBuilder.MaxCachedUsers
allow setting a limit on how many users' flag data can be saved in persistent local storage, or turning off persistence.- The
LaunchDarkly.Sdk.Json
namespace provides methods for converting types likeUser
andFeatureFlagsState
to and from JSON. - The
LaunchDarkly.Sdk.UserAttribute
type provides a less error-prone way to refer to user attribute names in configuration, and can also be used to get an arbitrary attribute from a user. - The
LaunchDarkly.Sdk.UnixMillisecondTime
type provides convenience methods for converting to and from the Unix epoch millisecond time format that LaunchDarkly uses for all timestamp values. - The SDK now periodically sends diagnostic data to LaunchDarkly, describing the version and configuration of the SDK, the architecture and version of the runtime platform, and performance statistics. No credentials, hostnames, or other identifiable values are included. This behavior can be disabled with
ConfigurationBuilder.DiagnosticOptOut
or configured withConfigurationBuilder.DiagnosticRecordingInterval
.
Changed (requirements/dependencies/build):
- .NET Standard 1.6 is no longer supported.
- The SDK no longer has a dependency on
Common.Logging
. Instead, it uses a similar but simpler logging facade, theLaunchDarkly.Logging
package, which has adapters for various logging destinations. - The SDK no longer has a dependency on the Json.NET library (a.k.a.
Newtonsoft.Json
), but instead uses a lightweight custom JSON serializer and deserializer. This removes the potential for dependency version conflicts in applications that use Json.NET for their own purposes, and reduces the number of dependencies in applications that do not use Json.NET. If you do use Json.NET and you want to use it with SDK data types likeUser
andLdValue
, seeLaunchDarkly.CommonSdk.JsonNet
. Those types also serialize/deserialize correctly with theSystem.Text.Json
API on platforms where that API is available.
Changed (API changes):
- The base namespace has changed: types that were previously in
LaunchDarkly.Client
are now inLaunchDarkly.Sdk
, and types that were previously inLaunchDarkly.Xamarin
are now inLaunchDarkly.Sdk.Client
. TheLaunchDarkly.Sdk
namespace contains types that are not specific to the client-side .NET SDK (that is, they are also used by the server-side .NET SDK):EvaluationDetail
,LdValue
,User
, andUserBuilder
. Types that are specific to the client-side .NET SDK, such asConfiguration
andLdClient
, are inLaunchDarkly.Sdk.Client
. User
andConfiguration
objects are now immutable. To specify properties for these classes, you must now useUser.Builder
andConfiguration.Builder
.Configuration.Builder
now returns a concrete type rather than an interface.EvaluationDetail
is now a struct type rather than a class.EvaluationReason
is now a single struct type rather than a base class with subclasses.EvaluationReasonKind
andEvaluationErrorKind
constants now use .Net-style naming (RuleMatch
) rather than Java-style naming (RULE_MATCH
). Their JSON representations are unchanged.- The
ILdClient
interface is now inLaunchDarkly.Sdk.Client.Interfaces
instead of the main namespace. - The
ILdClientExtensions
methodsEnumVariation<T>
andEnumVariationDetail<T>
now have type constraints to enforce thatT
really is anenum
type.
Changed (behavioral changes):
- The default event flush interval is now 30 seconds on mobile platforms, instead of 5 seconds. This is consistent with the other mobile SDKs and is intended to reduce network traffic.
- Logging now uses a simpler, more stable set of logger names instead of using the names of specific implementation classes that are subject to change. General messages are logged under
LaunchDarkly.Sdk.Xamarin.LdClient
, while messages about specific areas of functionality are logged under that name plus.DataSource
(streaming, polling, file data, etc.),.DataStore
(database integrations),.Evaluation
(unexpected errors during flag evaluations), or.Events
(analytics event processing).
Fixed:
- The SDK was deciding whether to send analytics events based on the
Offline
property of the original SDK configuration, rather than whether the SDK is currently in offline mode or not.
Removed:
- All types and methods that were shown as deprecated/
Obsolete
in the last 1.x release have been removed.
1.2.2
[1.2.2] - 2021-04-06
Fixed:
- The SDK was failing to get flags in streaming mode when connecting to a LaunchDarkly Relay Proxy instance.
1.2.1
[1.2.1] - 2021-03-30
Fixed:
- Removed unnecessary dependencies on
Xamarin.Android.Support.Core.Utils
andXamarin.Android.Support.CustomTabs
. (Thanks, Vladimir-Mischenchuk!) - Setting custom base URIs now works correctly even if the base URI includes a path prefix (such as you might use with a reverse proxy that rewrites request URIs). (#26)
- Fixed the base64 encoding of user properties in request URIs to use the URL-safe variant of base64.
1.2.0
[1.2.0] - 2020-01-15
Added:
- Added
ILdClient
extension methodsEnumVariation
andEnumVariationDetail
, which convert strings to enums. User.Secondary
,IUserBuilder.Secondary
(replacesSecondaryKey
).EvaluationReason
static methods and properties for creating reason instances.LdValue
helpers for dealing with array/object values, without having to use an intermediateList
orDictionary
:BuildArray
,BuildObject
,Count
,Get
.LdValue.Parse()
.
Changed:
EvaluationReason
properties all exist on the base class now, so for instance you do not need to cast toRuleMatch
to get theRuleId
property. This is in preparation for a future API change in whichEvaluationReason
will become a struct instead of a base class.
Fixed:
- Calling
Identify
orIdentifyAsync
with a user that has a null key andAnonymous(true)
-- which should generate a unique key for the anonymous user-- did not work. The symptom was that the client would fail to retrieve the flags, and the call would either never complete (forIdentifyAsync
) or time out (forIdentify
). This has been fixed. - Improved memory usage and performance when processing analytics events: the SDK now encodes event data to JSON directly, instead of creating intermediate objects and serializing them via reflection.
- When parsing arbitrary JSON values, the SDK now always stores them internally as
LdValue
rather thanJToken
. This means that no additional copying step is required when the application accesses that value, if it is of a complex type. LdValue.Equals()
incorrectly returned true for object (dictionary) values that were not equal.- The SDK now specifies a uniquely identifiable request header when sending events to LaunchDarkly to ensure that events are only processed once, even if the SDK sends them two times due to a failed initial attempt.
Deprecated:
IUserBuilder.SecondaryKey
,User.SecondaryKey
.EvaluationReason
subclasses. Use only the base class properties and methods to ensure compatibility with future versions.
1.1.1
[1.1.1] - 2019-10-23
Fixed:
- The JSON serialization of
User
was producing an extraAnonymous
property in addition toanonymous
. If Newtonsoft.Json was configured globally to force all properties to lowercase, this would cause an exception when serializing a user since the two properties would end up with the same name. (#22)
1.1.0
[1.1.0] - 2019-10-17
Added:
- Added support for upcoming LaunchDarkly experimentation features. See
ILdClient.Track(string, LdValue, double)
. User.AnonymousOptional
andIUserBuilder.AnonymousOptional
allow treating theAnonymous
property as nullable (necessary for consistency with other SDKs). See note about this under Fixed.- Added
LaunchDarkly.Logging.ConsoleAdapter
as a convenience for quickly enabling console logging; this is equivalent toCommon.Logging.Simple.ConsoleOutLoggerFactoryAdapter
, but the latter is not available on some platforms.
Fixed:
Configuration.Builder
was not setting a default value for theBackgroundPollingInterval
property. As a result, if you did not set the property explicitly, the SDK would throw an error when the application went into the background on mobile platforms.IUserBuilder
was incorrectly setting the user'sAnonymous
property tonull
even if it had been explicitly set tofalse
. Null and false behave the same in terms of LaunchDarkly's user indexing behavior, but currently it is possible to create a feature flag rule that treats them differently. SoIUserBuilder.Anonymous(false)
now correctly sets it tofalse
, just as the deprecated methodUserExtensions.WithAnonymous(false)
would.LdValue.Convert.Long
was mistakenly converting to anint
rather than along
. (CommonSdk #32)