using System.Threading.Tasks;
using PipServices3.Commons.Config;
using PipServices3.Commons.Refer;
using PipServices3.Commons.Run;

class MyCustomPersistence
{
    // Custom implementation using any persistence framework
}

class MyCustomPersistenceWrapper : IConfigurable, IReferenceable, IOpenable
{
    public ConfigParams _config = new ConfigParams();
    public MyCustomPersistence _persistence;

    public void Configure(ConfigParams config)
    {
        // Store config parameters
        this._config = config ?? this._config;
    }

    public void SetReferences(IReferences references)
    {
        // Retrieve whatever references you may need
    }

    public bool IsOpen()
    {
        return this._persistence != null;
    }

    public Task OpenAsync(string correlationId)
    {
        if (this._persistence != null) return;

        // Create custom persistence
        this._persistence = new MyCustomPersistence();

        // Configure custom persistence
        ...

        // Open and connect to the database
        await this._persistence.connect();
    }

    public Task CloseAsync(string correlationId)
    {
        if (this._persistence == null) return;

        // Disconnect from the database and close
        await this._persistence.disconnect();
        this._persistence = null;
    }

    public void CustomMethod(...)
    {
        // Delegate operations to custom persistence
        return await this._persistence.customMethod(...);
    }
}