Skip to content

Commit 4fe89cb

Browse files
authored
update README.md (#130)
Co-authored-by: Wenxi Zeng <[email protected]>
1 parent 7f2a8a1 commit 4fe89cb

File tree

1 file changed

+105
-0
lines changed

1 file changed

+105
-0
lines changed

README.md

+105
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@ This library is one of Segment’s most popular Flagship libraries. It is active
1414
- [Plugin Architecture](#plugin-architecture)
1515
- [Adding a plugin](#adding-a-plugin)
1616
- [Utility Methods](#utility-methods)
17+
- [Enrichment Closure](#enrichment-closure)
1718
- [Controlling Upload With Flush Policies](#controlling-upload-with-flush-policies)
1819
- [Handling Errors](#handling-errors)
1920
- [Customize HTTP Client](#customize-http-client)
2021
- [Customize Storage](#customize-storage)
2122
- [Json Library](#json-library)
2223
- [Samples](#samples)
24+
- [FAQs](#faqs)
2325
- [Compatibility](#compatibility)
2426
- [Changelog](#changelog)
2527
- [Contributing](#contributing)
@@ -90,6 +92,7 @@ To get started with the Analytics-CSharp library:
9092
| `storageProvider` | Default set to `DefaultStorageProvider`. <br>This set how you want your data to be stored. <br> `DefaultStorageProvider` is used by default which stores data to local storage. `InMemoryStorageProvider` is also provided in the library. <br>You can also write your own storage solution by implementing `IStorageProvider` and `IStorage` |
9193
| `httpClientProvider` | Default set to `DefaultHTTPClientProvider`. <br>This set a http client provider for analytics use to do network activities. The default provider uses System.Net.Http for network activities. |
9294
| `flushPolicies` | Default set to `null`. <br>This set custom flush policies to tell analytics when and how to flush. By default, it converts `flushAt` and `flushInterval` to `CountFlushPolicy` and `FrequencyFlushPolicy`. If a value is given, it overwrites `flushAt` and `flushInterval`. |
95+
| `eventPipelineProvider` | The default is `EventPipelineProvider`. <br>This sets a custom event pipeline to define how Analytics handles events. The default `EventPipelineProvider` processes events asynchronously. Use `SyncEventPipelineProvider` to make manual flush operations synchronous. |
9396

9497
## Tracking Methods
9598

@@ -361,6 +364,22 @@ The `reset` method clears the SDK’s internal stores for the current user and g
361364
analytics.Reset()
362365
```
363366

367+
## Enrichment Closure
368+
To modify the properties of an event, you can either write an enrichment plugin that applies changes to all events, or pass an enrichment closure to the analytics call to apply changes to a specific event.
369+
370+
```c#
371+
analytics.Track("MyEvent", properties, @event =>
372+
{
373+
if (@event is TrackEvent trackEvent)
374+
{
375+
// update properties of this event
376+
trackEvent.UserId = "foo";
377+
}
378+
379+
return @event;
380+
});
381+
```
382+
364383
## Controlling Upload With Flush Policies
365384
To more granularly control when events are uploaded you can use `FlushPolicies`. **This will override any setting on `flushAt` and `flushInterval`, but you can use `CountFlushPolicy` and `FrequencyFlushPolicy` to have the same behaviour respectively.**
366385

@@ -584,6 +603,92 @@ For sample usages of the SDK in specific platforms, checkout the following:
584603
| | [Custom Logger](https://github.com/segmentio/Analytics-CSharp/tree/main/Samples/ConsoleSample/SegmentLogger.cs) |
585604
| | [Custom Error Handler](https://github.com/segmentio/Analytics-CSharp/tree/main/Samples/ConsoleSample/NetworkErrorHandler.cs) |
586605
606+
## FAQs
607+
608+
### Should I make Analytics a singleton or scoped in .NET?
609+
610+
The SDK supports both, but be aware of the implications of choosing one over the other:
611+
612+
| Feature | Singleton | Scoped |
613+
|--|--|--|
614+
| **Fetch Settings** | Settings are fetched only once at application startup. | Settings are fetched on every request. |
615+
| **Flush** | Supports both async and sync flush. | Requires sync flush. Should flush per event or on page redirect/close to avoid data loss. |
616+
| **Internal State** | The 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. |
617+
| **UserId for Events** | Requires 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`. |
618+
| **Storage** | Supports both local storage and in-memory storage. | Requires in-memory storage. (*Support for local storage is in progress*.) |
619+
620+
621+
In a nutshell, to register Analytics as singleton:
622+
623+
```c#
624+
var configuration = new Configuration(
625+
writeKey: "YOUR_WRITE_KEY",
626+
// Use in-memory storage to keep the SDK stateless.
627+
// The default storage also works if you want to persist events.
628+
storageProvider: new InMemoryStorageProvider(),
629+
// Use a synchronous pipeline to make manual flush operations synchronized.
630+
eventPipelineProvider: new SyncEventPipelineProvider()
631+
);
632+
633+
var analytics = new Analytics(configuration);
634+
635+
// Add UserIdPlugin to associate events with the provided userId.
636+
analytics.Add(new UserIdPlugin());
637+
638+
// Call analytics APIs with a userId. The UserIdPlugin will update the event with the provided userId.
639+
analytics.Track("user123", "foo", properties);
640+
641+
// This is a blocking call due to SyncEventPipelineProvider.
642+
// Use the default EventPipelineProvider for asynchronous flush.
643+
analytics.Flush();
644+
645+
// Register Analytics as a singleton.
646+
```
647+
648+
To register Analytics as scoped:
649+
650+
```c#
651+
var configuration = new Configuration(
652+
writeKey: "YOUR_WRITE_KEY",
653+
// Requires in-memory storage.
654+
storageProvider: new InMemoryStorageProvider(),
655+
// Flush per event to prevent data loss in case of a page close.
656+
// Alternatively, manually flush on page close.
657+
flushAt: 1,
658+
// Requires a synchronous flush.
659+
eventPipelineProvider: new SyncEventPipelineProvider()
660+
);
661+
662+
var analytics = new Analytics(configuration);
663+
664+
// Update the internal state with a userId.
665+
analytics.Identify("user123");
666+
667+
// Subsequent events are auto-stamped with the userId from the internal state.
668+
analytics.Track("foo", properties);
669+
670+
// This is a blocking call due to SyncEventPipelineProvider.
671+
analytics.Flush();
672+
673+
// Register Analytics as scoped.
674+
```
675+
676+
### Which JSON library does this SDK use?
677+
678+
The SDK supports `.netstandard 1.3` and `.netstandard 2.0` and automatically selects the internal JSON library based on the target framework:
679+
680+
* In `.netstandard 1.3`, the SDK uses `Newtonsoft Json.NET`
681+
* In `.netstandard 2.0`, the SDK uses `System.Text.Json`
682+
683+
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:
684+
685+
1. You are targeting `.netstandard 2.0`.
686+
2. Your properties use`Newtonsoft Json.NET` objects or arrays.
687+
688+
To resolve this, you can:
689+
* Option 1: Target `.netstandard 1.3`
690+
* Option 2: Upgrade your JSON library to `System.Text.Json`
691+
587692
## Compatibility
588693
This library targets `.NET Standard 1.3` and `.NET Standard 2.0`. Checkout [here](https://www.nuget.org/packages/Segment.Analytics.CSharp/#supportedframeworks-body-tab) for compatible platforms.
589694

0 commit comments

Comments
 (0)