# Custom Handler

If functionality is needed that isn't included in the built-in modules or extensions, the hybrid integration can be extended to provide custom modules with properties, methods, and events.

{% hint style="info" %}
Contact [**sales@wisej.com**](mailto:sales@wisej.com) to get a quote for custom integrations.
{% endhint %}

## Handlers

Handlers are used to link the server-side and client-side (MAUI) integrations. Handlers implement the **IClientHandler** interface and provide several methods for processing requests from a Wisej.NET application which can be used to wire custom properties, methods, and events.

**Example Client-Side Handler Integration**

```csharp
/// <summary>
/// Client-side integration for mathematical operations.
/// </summary>
internal class MathHandler : IClientHandler
{
	string IClientHandler.Identifier => "math";

	bool IClientHandler.ProcessRequest(DeviceRequest request)
	{
		var num1 = request.Arguments[0];
		var num2 = request.Arguments[1];
	
		switch (request.Action)
		{
			case "add":
				App.FireModalResponse(Add(num1, num2));
				return true;

			case "subtract":
				App.FireModalResponse(Subtract(num1, num2));
				return true;

			default:
				return false;
		}
	}

	void IClientHandler.Reset()
	{
		// reset the UI changes.
	}

	private DeviceResponse Add(int num1, int num2)
	{
		return new DeviceResponse(num1 + num2);			
	}

	private DeviceResponse Subtract(int num1, int num2) 
	{
		return new DeviceResponse(num1 - num2);			
	}
}
```

**Registering Client-Side Handler**

```csharp
App.RegisterClientHandler(typeof(MathHandler));
```

**Example Usage on Server**

```csharp
var result = Device.PostModalMessage("math", "add", 1, 2);
```

## Firing Native Events to the Server

If you only need to push data from the native MAUI app to the Wisej.NET server, you don't need to build a full custom request/response handler.

Use `Wisej.Hybrid.Native.App.FireEvent(...)` on the native side and handle the event on the server using `Device.RegisterEventListener(...)`.

This is useful for scenarios such as:

* barcode or RFID scans received through Android intents
* native lifecycle notifications
* custom data coming from platform-specific code

**Example Client-Side Event**

```csharp
public class BarcodeDispatcher : IBarcodeDispatcher
{
	public void DispatchBarcode(string barcode, string type)
	{
		Wisej.Hybrid.Native.App.FireEvent("barcode", "scan", new
		{
			Barcode = barcode,
			Type = type
		});
	}
}
```

You can also use the convenience overload when the default `application` handler is enough:

```csharp
Wisej.Hybrid.Native.App.FireEvent("sampleEvent", new
{
	Message = "Native app loaded."
});
```

**Example Usage on Server**

```csharp
Device.RegisterEventListener("barcode", e =>
{
	if (e.Type == "scan")
	{
		var barcode = e.Data?.Barcode?.ToString();
		var type = e.Data?.Type?.ToString();

		// process the scan here
	}
});
```

{% hint style="info" %}
Use a custom `IClientHandler` when the server needs to invoke native actions or request a response. Use `App.FireEvent(...)` when the native side only needs to publish an event back to the server.
{% endhint %}

## Information Providers

Information providers are used to extend the **Device.Info** member. They provide information on startup about the client hybrid device and its capabilities. New information providers can be registered by adding a new **IClientInfoProvider**.

**Example Client-Side Information Provider**

```csharp
/// <summary>
/// Provides a random Guid on startup.
/// </summary>
public class GuidInfoProvider : IClientInfoProvider
{
	/// <summary>
	/// Creates a new instance of <see cref="GuidInfoProvider"/>.
	/// </summary>
	public GuidInfoProvider() { }

	Dictionary<string, string> IClientInfoProvider.ProvideConfiguration()
	{
		var config = new Dictionary<string, string>();

		foreach (var property in typeof(VersionTracking).GetProperties())
		{
			config.Add("guid", Guid.NewGuid().ToString());
		}

		return config;
	}
}
```

**Example Implementation on Server**

```csharp
public class DeviceGuidInfo
{
	public DeviceGuidInfo()
	{
		var base64 = Application.QueryString["info"];
		using (var stream = new MemoryStream(Convert.FromBase64String(base64)))
		{
			var info = JSON.Parse(stream);

			this.Guid = info.guid;
		}
	}
	
	/// A random guid.
	public string Guid
	{
		get;
		internal set;
	}
}
```

**Example Usage on Server**

```csharp
var guid = Device.Info.Get<DeviceGuidInfo>().Guid;
```
