Skip to contentSkip to navigationSkip to topbar
On this page
Looking for more inspiration?Visit the
(information)
You're in the right place! Segment documentation is now part of Twilio Docs. The content you are used to is still here—just in a new home with a refreshed look.

Analytics-CSharp (C#) Migration Guide


If you're currently using Analytics.NET or Analytics.Xamarin to send data to Segment, please follow the steps below to migrate to the Analytics-CSharp library.

(success)

Success!

Analytics-C# does not include v1 as part of the url address. If you are using the Segment EU endpoint, you will have to pass it manually. For instance, eu1.api.segmentapis.com/v1

You can update to Analytics-CSharp in 3 steps:

  1. Bundle Analytics-CSharp into your app and remove your previous SDK.
  2. Change the namespaces.
  3. (Optional) Use Reset to stay anonymous.

Migration steps

migration-steps page anchor
  1. Add the Analytics-CSharp dependency to your project.


    Before:

    dotnet add package Analytics --version <VERSION>


    Before (for Xamarin users only):

    git clone https://github.com/segmentio/Analytics.Xamarin.git


    After:

    dotnet add package Segment.Analytics.CSharp --version <VERSION>
  2. Replace namespaces.


    Before:

    1
    using Segment;
    2
    using Segment.Flush;
    3
    using Segment.Model;
    4
    using Segment.Request;


    After:

    1
    using Segment.Analytics;
    2
    using Segment.Analytics.Compat;
  3. (Required for .NET users) Add UserIdPlugin to Analytics.

    Analytics-CSharp, by default, attaches an internal state userId to each event. The UserIdPlugin, instead, attaches the userId provided in analytics calls directly to the event.


    After:

    analytics.Add(new UserIdPlugin());
  4. (Optional) Update calls that resets the anonymous ID.

    The old SDK requires you to provide the anonymous ID. The new SDK generates an Anonymous ID for you if you never call analytics.Identify. If you call Identify and want to go back to anonymous, the new SDK provides a Reset function to achieve that.


    Before:

    1
    Analytics.Client.Page(null, "Login", new Properties(), new Options()
    2
    .SetAnonymousId("some-id"));


    After:

    analytics.Reset();

Optional changes for unit tests

optional-changes-for-unit-tests page anchor

Change your development settings if you would like to make analytics run synchronously for testing purposes.


Before:

Analytics.Initialize("YOUR_WRITE_KEY", new Config().SetAsync(false));


After:

1
var configuration = new Configuration("YOUR WRITE KEY",
2
useSynchronizeDispatcher: true,
3
// provide a defaultSettings in case the SDK failed to fetch settings in test environment
4
defaultSettings: new Settings
5
{
6
Integrations = new JsonObject
7
{
8
["Segment.io"] = new JsonObject
9
{
10
["apiKey"] = "YOUR WRITE KEY"
11
}
12
}
13
}
14
);
15
var analytics = new Analytics(configuration);

Should I make Analytics a singleton or scoped in .NET?

should-i-make-analytics-a-singleton-or-scoped-in-net page anchor

The SDK supports both, but be aware of the implications of choosing one over the other:

FeatureSingletonScoped
Fetch SettingsSettings are fetched only once at application startup.Settings are fetched on every request.
FlushSupports both async and sync flush.Requires sync flush. Should flush per event or on page redirect/close to avoid data loss.
Internal StateThe internal state (userId, anonId, etc.) is shared across sessions and cannot be used. (This is an overhead we are working to minimize.)The internal state is safe to use since a new instance is created per request.
UserId for EventsRequires adding UserIdPlugin and calling analytics APIs with userId to associate the correct userId with events.No need for UserIdPlugin or passing userId in API calls. Instead, call analytics.Identify() to update the internal state with the userId. Successive events are auto-stamped with that userId.
StorageSupports both local storage and in-memory storage.Requires in-memory storage. (Support for local storage is in progress.)

In a nutshell, to register Analytics as singleton:

1
var configuration = new Configuration(
2
writeKey: "YOUR_WRITE_KEY",
3
// Use in-memory storage to keep the SDK stateless.
4
// The default storage also works if you want to persist events.
5
storageProvider: new InMemoryStorageProvider(),
6
// Use a synchronous pipeline to make manual flush operations synchronized.
7
eventPipelineProvider: new SyncEventPipelineProvider()
8
);
9
10
var analytics = new Analytics(configuration);
11
12
// Add UserIdPlugin to associate events with the provided userId.
13
analytics.Add(new UserIdPlugin());
14
15
// Call analytics APIs with a userId. The UserIdPlugin will update the event with the provided userId.
16
analytics.Track("user123", "foo", properties);
17
18
// This is a blocking call due to SyncEventPipelineProvider.
19
// Use the default EventPipelineProvider for asynchronous flush.
20
analytics.Flush();
21
22
// Register Analytics as a singleton.

To register Analytics as scoped:

1
var configuration = new Configuration(
2
writeKey: "YOUR_WRITE_KEY",
3
// Requires in-memory storage.
4
storageProvider: new InMemoryStorageProvider(),
5
// Flush per event to prevent data loss in case of a page close.
6
// Alternatively, manually flush on page close.
7
flushAt: 1,
8
// Requires a synchronous flush.
9
eventPipelineProvider: new SyncEventPipelineProvider()
10
);
11
12
var analytics = new Analytics(configuration);
13
14
// Update the internal state with a userId.
15
analytics.Identify("user123");
16
17
// Subsequent events are auto-stamped with the userId from the internal state.
18
analytics.Track("foo", properties);
19
20
// This is a blocking call due to SyncEventPipelineProvider.
21
analytics.Flush();
22
23
// Register Analytics as scoped.

Which JSON library does this SDK use?

which-json-library-does-this-sdk-use page anchor

The SDK supports .netstandard 1.3 and .netstandard 2.0 and automatically selects the internal JSON library based on the target framework:

  • In .netstandard 1.3, the SDK uses Newtonsoft Json.NET
  • In .netstandard 2.0, the SDK uses System.Text.Json

Be ware that both Analytics.NET and Analytics.Xamarin use Newtonsoft Json.NET. If you encounter issues where JSON dictionary values are turned into empty arrays, it is likely that:

  1. You are targeting .netstandard 2.0.
  2. Your properties useNewtonsoft Json.NET objects or arrays.

To resolve this, you can:

  • Option 1: Target .netstandard 1.3
  • Option 2: Upgrade your JSON library to System.Text.Json