Design

This document provides an overview of the design of the library as well as general rules to help you understand how to interact with it.

Objects

All the library objects can be divided into the following categories:

  • service objects;
  • immutable data objects.

Service objects allow performing some operations when data objects just hold the data. Service objects can use the data objects.

Objects like IEngine, IBrowser, IBrowserSettings, IFrame, IDocument, IJsObject instances are service objects. While EngineOptions, Size, Rectangle are immutable data objects.

Instantiation

To create an immutable data object or a service object, use its constructor, builder, or one of its static methods. Here is an example of using the builder:

EngineOptions options = 
    new EngineOptions.Builder 
    {
        RenderingMode = RenderingMode.HardwareAccelerated,
        Language = Language.EnglishUs
    }
    .Build();
IEngine engine = EngineFactory.Create(options);

Destruction

Every service object that must be disposed manually implements the IDisposable interface. To dispose a service object and release all allocated memory and resources, call the IDisposable.Dispose() method. For example:

engine.Dispose();

Some service objects such as IFrame can be disposed automatically, for example, when the web page is unloaded. These objects implement the IAutoDisposable interface.

If you use an already disposed object, ObjectDisposedException occurs.

Relationship

The lifecycle of a service object can depend on the lifecycle of another object. When the service object is disposed, all service objects depending on it are released automatically. For example:

  • When you dispose the IEngine, all its IBrowser instances are released automatically;
  • When you dispose the IBrowser, all its IFrame instances are disposed automatically.

Methods

Methods that return Task<T> instance are executed asynchronously. If the method returns some value, it is executed synchronously blocking the current thread execution until the return value is received.

Handlers

Each object that allows registering handlers has the properties of type IHandler<in T> or IHandler<in T, out TResult> interface. To register and unregister a handler, use the property setters and getters.

There are default implementations of the IHandler<in T, out TResult> interface:

  • Handler<T, TResult> class allows wrapping lambdas and method groups;
  • AsyncHandler<T, TResult> class allows wrapping async lambdas and method groups or lambdas and method groups that return Task<TResult>.

Async

Example below demonstrates how to register an asynchronous handler that returns a Task to provide a response asynchronously:

browser.ShowContextMenuHandler =
    new AsyncHandler<ShowContextMenuParameters, ShowContextMenuResponse>(ShowContextMenu);

// An async method that is declared in the same class:
private async Task<ShowContextMenuResponse> ShowContextMenu(ShowContextMenuParameters p)
{
    //...
}

The task result can be provided asynchronously from a different thread.

Provide a response through the returned Task argument, otherwise IEngine waits for the response until termination.

Sync

Example below demonstrates how to register and unregister a regular Handler that returns response through a return value:

browser.CreatePopupHandler = new Handler<CreatePopupParameters, CreatePopupResponse>((p) =>
{
    return CreatePopupResponse.Create();
});

Threads

The library is not thread-safe, so avoid working with the library from different threads at the same time.

Go Top