Writing a Record Cabinet provider
A provider connects Record Cabinet to another document system. If your organization has developers, they can write one in house. This guide covers what a provider must do.
This guide applies to Record Cabinet version 0.9.0.
Overview
Record Cabinet finds providers when it starts, by scanning for assemblies in its own folder. A provider is a .NET assembly with a class that implements IDataSourceProvider. No configuration file or code change is needed.
Once a provider is in place, an administrator adds the repository in Record Cabinet. Record Cabinet then uses the provider to browse cabinets and retrieve documents from the connected system. Repositories that use a custom provider are always read-only. Their cabinets cannot be edited, deleted, or written to.
Provider projects reference RecordCabinet.Core.dll, which is in the Record Cabinet installation folder.
What a provider must implement
The provider class implements IDataSourceProvider. It returns an IRepositoryContext, which supplies the repositories that Record Cabinet reads from. If an assembly contains more than one qualifying class, each one is registered separately.
IDataSourceProvider
public interface IDataSourceProvider
{
string DisplayName { get; }
Task<bool> CanHandleAsync(DbConnectionOptions connection);
IRepositoryContext GetContext(DataSource dataSource);
}
DisplayNameis the name of the document system, shown to administrators as the repository type. Use the product's name, not a class or assembly name.CanHandleAsyncis called when an administrator tests a connection. Open a connection with the supplied options and returntrueif the database is one your provider recognizes. Returnfalse, and never throw, if it is unreachable or not recognized.GetContextis called when Record Cabinet needs to read from a repository your provider owns. Return anIRepositoryContextbacked by the supplied data source. ItsConnectionis never null at this point.
IRepositoryContext
public interface IRepositoryContext
{
ICabinetRepository CabinetRepository { get; }
IDocumentRepository DocumentRepository { get; }
IDocumentContentResolver ContentResolver { get; }
Task<RepositoryStats> GetStatsAsync();
}
Each property must return a non-null implementation, and GetStatsAsync must never return null.
Repository interfaces
ICabinetRepository
| Member | Description |
|---|---|
GetAsync() | Returns all cabinets visible through this repository. |
GetAsync(short cabinetId) | Returns the cabinet with the given Id. Throws if it is not found. |
Every cabinet your provider returns is listed in Record Cabinet. Create each one with the Cabinet.FromProvider factory method, passing the cabinet's id, name, and ordered fields. You can also pass a description and creation date if your system has them. Record Cabinet treats provider cabinets as locked.
IDocumentRepository
| Member | Description |
|---|---|
GetAsync(short cabinetId, int limit) | Returns up to limit document indices for the cabinet. |
SearchAsync(Criteria criteria) | Returns indices matching the search criteria. |
Both members must return their indices already ordered. That order is what the document list shows, and nothing after your provider sorts it again. Choose the ordering that suits your source. When limit cuts the result short, return the indices your ordering puts first.
IDocumentContentResolver
| Member | Description |
|---|---|
GetContentAsync(short cabinetId, int documentId) | Returns the primary renderable content for a document. |
GetContentPartsAsync(short cabinetId, int documentId) | Returns all content parts for a document. |
Statistics
GetStatsAsync returns a RepositoryStats with a display name and a CabinetStats entry for each cabinet, holding its document and index counts. Record Cabinet shows these on the administration home page.
Assembly requirements
A provider assembly must:
- Target
net10.0and be binary-compatible with the installed application. - Reference
RecordCabinet.Coreas shipped with the application. - Contain a provider class that is public, not abstract, and has a public parameterless constructor. Record Cabinet creates each candidate by reflection with no arguments. A class that cannot be created this way is skipped without a message, as is an assembly that cannot be loaded.
There are no file naming rules.
The class name is a published identifier
Record Cabinet stores the provider's full type name with every repository configured against it, and uses that name at startup to pair the repository with its provider. Treat the namespace and class name as part of your published contract. If you rename or move the class after a repository has been set up, the repository stops loading until an administrator adds it again.
Deployment
- Build the provider assembly for
net10.0. - Copy the
.dll, and any dependencies not already present, into the Record Cabinet application folder, the one that containsRecordCabinet.Web.dll. - Restart the web application. The provider is discovered when it starts.
- As an administrator, add a repository and test the connection. If the provider recognizes the database, it is identified automatically. Save the repository to make its cabinets available.
Questions about a legacy system, or want me to write the provider? Contact me.