Session: How to Subscribe to Events
-
Events allow users to perform custom actions in response to operations made in a
Document Store
or aSession
. -
An event is invoked when the selected action is executed on an entity, or querying is performed.
-
Subscribing to an event within a
Session
is valid only for this session.E.g., to invoke an event after SaveChanges() is called by this session only, use -
session.Advanced.OnAfterSaveChanges += OnAfterSaveChangesEvent;
-
Subscribing to an event at the
DocumentStore
level subscribes to this event in all subsequent sessions.E.g., to invoke an event after SaveChanges() is called by any subsequent session, use -
store.OnAfterSaveChanges += OnAfterSaveChangesEvent;
-
In this Page:
OnBeforeStore
This event is invoked as a part of SaveChanges
but before it is actually sent to the server.
It should be defined with this signature:
private void OnBeforeStoreEvent(object sender, BeforeStoreEventArgs args);
Parameters | Type | Description |
---|---|---|
sender | IDocumentSession |
The session on which SaveChanges() has been called, triggering this event |
args | BeforeStoreEventArgs |
args contains the session on which SaveChanges() has been called, the ID of the document being Stored, the document's metadata, and the document itself. |
The class BeforeStoreEventArgs
:
public class BeforeStoreEventArgs
{
public InMemoryDocumentSessionOperations Session;
public string DocumentId;
public object Entity;
public IMetadataDictionary DocumentMetadata;
}
Example
Say we want to discontinue all of the products that are not in stock.
private void OnBeforeStoreEvent(object sender, BeforeStoreEventArgs args)
{
var product = args.Entity as Product;
if (product?.UnitsInStock == 0)
{
product.Discontinued = true;
}
}
After we subscribe to the event, every stored entity will invoke the method.
// Subscribe to the event
session.Advanced.OnBeforeStore += OnBeforeStoreEvent;
session.Store(new Product
{
Name = "RavenDB v3.5",
UnitsInStock = 0
});
session.Store(new Product
{
Name = "RavenDB v4.0",
UnitsInStock = 1000
});
session.SaveChanges(); // Here the method is invoked
OnBeforeDelete
This event is invoked by Delete(id)
or Delete(entity)
. It is only executed when SaveChanges()
is called, but before the commands are actually sent to the server.
It should be defined with this signature:
private void OnBeforeDeleteEvent(object sender, BeforeDeleteEventArgs args);
Parameters | Type | Description |
---|---|---|
sender | IDocumentSession |
The session on which SaveChanges() has been called, triggering this event |
args | BeforeDeleteEventArgs |
args contains the session on which SaveChanges() has been called, the ID of the document being deleted, the document's metadata, and the document itself. |
The class BeforeDeleteEventArgs
:
public class BeforeDeleteEventArgs
{
public InMemoryDocumentSessionOperations Session;
public string DocumentId;
public object Entity;
public IMetadataDictionary DocumentMetadata;
}
Example
To prevent anyone from deleting entities we can create a method as follows:
private void OnBeforeDeleteEvent(object sender, BeforeDeleteEventArgs args)
{
throw new NotSupportedException();
}
and subscribe it to the session:
// Subscribe to the event
session.Advanced.OnBeforeDelete += OnBeforeDeleteEvent;
var product = session.Load<Product>("products/1-A");
var product2 = session.Load<Product>("products/2-A");
// OnBeforeDelete is triggered whether you
// call Delete() on an entity or on its ID
session.Delete(product);
session.SaveChanges(); // NotSupportedException will be thrown
session.Delete("products/2-A");
session.SaveChanges(); // NotSupportedException will be thrown
OnAfterSaveChanges
This event is invoked after the SaveChanges
is returned.
It should be defined with this signature:
private void OnAfterSaveChangesEvent(object sender, AfterSaveChangesEventArgs args);
Parameters | Type | Description |
---|---|---|
sender | IDocumentSession |
The session on which SaveChanges() has been called, triggering this event |
args | AfterSaveChangesEventArgs |
args contains the session on which SaveChanges() has been called, the ID of the document being deleted, and the document itself. |
The class AfterSaveChangesEventArgs
:
public class AfterSaveChangesEventArgs
{
public InMemoryDocumentSessionOperations Session;
public string DocumentId;
public object Entity;
}
Example
If we want to log each entity that was saved, we can create a method as follows:
private void OnAfterSaveChangesEvent(object sender, AfterSaveChangesEventArgs args)
{
if (Log.IsInfoEnabled)
Log.Info($"Document '{args.DocumentId}' was saved.");
}
OnBeforeQuery
This event is invoked just before the query is sent to the server. It should be defined with this signature:
private void OnBeforeQueryEvent(object sender, BeforeQueryEventArgs args);
Parameters | Type | Description |
---|---|---|
sender | IDocumentSession |
The session on which SaveChanges() has been called, triggering this event |
args | BeforeQueryEventArgs |
args contains the session on which SaveChanges() has been called, and the query's query customizations. |
The class BeforeQueryEventArgs
:
public class BeforeQueryEventArgs
{
public InMemoryDocumentSessionOperations Session;
public IDocumentQueryCustomization queryCustomization;
}
Example I
If you want to disable caching of all query results, you can implement the method as follows:
private void OnBeforeQueryEvent(object sender, BeforeQueryEventArgs args)
{
args.QueryCustomization.NoCaching();
}
Example II
If you want each query to wait for non-stale results you can create an event as follows:
private void OnBeforeQueryEvent(object sender, BeforeQueryEventArgs args)
{
args.QueryCustomization.WaitForNonStaleResults(TimeSpan.FromSeconds(30));
}
OnBeforeConversionToDocument
This event is invoked before conversion of an entity to blittable JSON document. E.g. it's called when sending a document to a server.
It should be defined with this signature:
private void OnBeforeConversionToDocumentEvent(object sender, BeforeConversionToDocumentEventArgs args);
Parameters | Type | Description |
---|---|---|
sender | IDocumentSession |
The session on which SaveChanges() has been called, triggering this event |
args | BeforeConversionToDocumentEventArgs |
args contains the session on which SaveChanges() has been called, the ID of the document being ConversionToDocumentd, and the document itself. |
The class BeforeConversionToDocumentEventArgs
:
public class BeforeConversionToDocumentEventArgs
{
public InMemoryDocumentSessionOperations Session;
public string DocumentId;
public object Entity;
}
Example
private void OnBeforeConversionToDocument(object sender, BeforeConversionToDocumentEventArgs args)
{
if (args.Entity is Item item)
item.Before = true;
}
OnAfterConversionToDocument
This event is invoked after conversion of an entity to blittable JSON document.
It should be defined with this signature:
private void OnAfterConversionToDocumentEvent(object sender, AfterConversionToDocumentEventArgs args);
Parameters | Type | Description |
---|---|---|
sender | IDocumentSession |
The session on which SaveChanges() has been called, triggering this event |
args | AfterConversionToDocumentEventArgs |
args contains the session on which SaveChanges() has been called, the ID of the document being ConversionToDocumentd, and the document itself. |
The class AfterConversionToDocumentEventArgs
:
public class AfterConversionToDocumentEventArgs
{
public InMemoryDocumentSessionOperations Session;
public string DocumentId;
public object Entity;
}
Example
private void OnAfterConversionToDocument(object sender, AfterConversionToDocumentEventArgs args)
{
if (args.Entity is Item item)
{
if (args.Document.Modifications == null)
args.Document.Modifications = new DynamicJsonValue();
args.Document.Modifications["After"] = true;
args.Document = args.Session.Context.ReadObject(args.Document, args.Id);
item.After = true;
}
}
OnBeforeConversionToEntity
This event is invoked before conversion of a JSON document to an entity. E.g. it's called when loading a document.
It takes the argument BeforeConversionToEntityEventArgs
, that consists of a JSON document, its ID and type, and the session instance.
private void OnBeforeConversionToEntity(object sender, BeforeConversionToEntityEventArgs args)
{
var document = args.Document;
if (document.Modifications == null)
document.Modifications = new DynamicJsonValue();
document.Modifications["Before"] = true;
args.Document = args.Session.Context.ReadObject(document, args.Id);
}
OnAfterConversionToEntity
This event is invoked after conversion of a JSON document to an entity. It takes the argument AfterConversionToEntityEventArgs
, that consists of a JSON document, its ID, the session instance and a converted entity.
private void OnAfterConversionToEntity(object sender, AfterConversionToEntityEventArgs args)
{
if (args.Entity is Item item)
item.After = true;
}