# Event Processors | Sentry for .NET for Android

Event processors can enrich events with additional, either globally or within a particular scope. Though event processors are similar to `BeforeSend` and `BeforeSendTransaction`, there are two key differences:

1. `BeforeSend` and `BeforeSendTransaction` are guaranteed to be run after all other processing, just before an event gets sent. Event processors run in an undetermined order, so changes to the event may still be made after the event processor runs.
2. `BeforeSend` and `BeforeSendTransaction` always run globally. Processors can be configured to run either globally or only within a particular scope.

## [Duplicate Event Detection](https://docs.sentry.io/platforms/dotnet/guides/android/enriching-events/event-processors.md#duplicate-event-detection)

By default, Sentry includes a global processor that detects and drops duplicate events.

This processor be configured by via `SentryOptions.DeduplicateMode` when initialising the Sentry SDK. This is a flag enum consisting of the following values:

* `DeduplicateMode.SameEvent`: Same event instance. Assumes no object reuse/pooling.
* `DeduplicateMode.SameExceptionInstance`: An exception that was captured twice.
* `DeduplicateMode.InnerException`: An exception already captured exists as an inner exception.
* `DeduplicateMode.AggregateException`: An exception already captured is part of the aggregate exception.
* `DeduplicateMode.All`: All modes combined.

The default value for `SentryOptions.DeduplicateMode` is `DeduplicateMode.All ^ DeduplicateMode.InnerException` (so all detected duplicate events will be dropped except those from inner exceptions). However, if we only wanted `SameEvent` and `SameExceptionInstance` events to be dropped, we could initialize the SDK as follows:

```csharp
SentrySdk.Init(options => {
  // ... configure other options here
  options.DeduplicateMode = DeduplicateMode.SameEvent | DeduplicateMode.SameExceptionInstance;
})
```

Alternatively, duplicate event detection can be disabled entirely by calling `DisableDuplicateEventDetection`:

```csharp
SentrySdk.Init(options => {
  // ... configure other options here
  options.DisableDuplicateEventDetection();
})
```

## [Custom event processors](https://docs.sentry.io/platforms/dotnet/guides/android/enriching-events/event-processors.md#custom-event-processors)

You can create your own event processors by implementing the `ISentryEventProcessor` interface. You can also create custom processors for transactions by implementing the `ISentryTransactionProcessor`.

```csharp
using Sentry.Extensibility;

public class CustomEventProcessor : ISentryEventProcessor
{
    public SentryEvent? Process(SentryEvent @event)
    {
        // Add anything to the event here
        // returning `null` will drop the event
        return @event;
    }
}
```

Processors run on every event sent once they've been added. While there are multiple ways of doing this, adding processors to the options ensures that they run with every event after initialization.

```csharp
options.AddEventProcessor(new CustomEventProcessor());
```

If `AddEventProcessor` has been added to the scope, it'll apply to both the current and the following scopes:

```csharp
SentrySdk.ConfigureScope(scope => scope.AddEventProcessor(new CustomEventProcessor()));
```

But if an event processor has only been added to a local scope using `withScope`, it'll only apply to events captured inside that scope.

```csharp
SentrySdk.WithScope(scope => scope.AddEventProcessor(new CustomEventProcessor()));
```
