Listeners: What are store listeners and how to work with them?
In order execute a custom action before or after a document is stored the IDocumentStoreListener
needs to be implemented:
public interface IDocumentStoreListener
{
/// <summary>
/// Invoked before the store request is sent to the server.
/// </summary>
/// <param name="key">The key.</param>
/// <param name="entityInstance">The entity instance.</param>
/// <param name="metadata">The metadata.</param>
/// <param name="original">The original document that was loaded from the server</param>
/// <returns>
/// Whatever the entity instance was modified and requires us re-serialize it.
/// Returning true would force re-serialization of the entity, returning false would
/// mean that any changes to the entityInstance would be ignored in the current SaveChanges call.
/// </returns>
bool BeforeStore(string key, object entityInstance, RavenJObject metadata,
RavenJObject original);
/// <summary>
/// Invoked after the store request is sent to the server.
/// </summary>
/// <param name="key">The key.</param>
/// <param name="entityInstance">The entity instance.</param>
/// <param name="metadata">The metadata.</param>
void AfterStore(string key, object entityInstance, RavenJObject metadata);
}
Example
To prevent anyone from adding documents with a certain key, you can create FilterForbiddenKeysDocumentListener
. In result the document with the specified forbidden id will not be stored.
public class FilterForbiddenKeysDocumentListener : IDocumentStoreListener
{
private readonly IList<string> forbiddenKeys = new List<string> { "system" };
public bool BeforeStore(string key, object entityInstance, RavenJObject metadata,
RavenJObject original)
{
if (forbiddenKeys.Any(x => x.ToLower().Equals(key)))
{
throw new InvalidOperationException($"Store a document with a key: {key} is forbidden");
}
return false;
}
public void AfterStore(string key, object entityInstance, RavenJObject metadata)
{
}
}