Customising How LightSpeed Connects to the Database
By default, a LightSpeed unit of work maps to a database connection. The unit of work opens the connection the first time it needs to talk to the database, and keeps it open until you dispose the unit of work.
This usage reflects the recommended pattern of keeping units of work short‑lived. For example, in a Web application using ‘unit of work per request,’ the unit of work lives just long enough to serve a page, so the database connection is quickly closed as well.
Some applications, particularly rich clients, use long-running units of work. This can create problems for the ‘connection per unit of work’ strategy, because a large number of idle clients can starve the database of connections, and because it increases the chance of the connection going into a faulted state, leaving the unit of work saddled with an unusable connection.
For cases such as these you can override the ‘connection per unit of work’ pattern by implementing a custom connection strategy. You can use this to gain finer control over how LightSpeed uses connections.
Implementing a Custom Connection Strategy
To implement a connection strategy, create a class that derives from ConnectionStrategy and overrides the Connection property and the Dispose(bool) method. Here is a simple connection strategy that opens a connection whenever it needs one, and leaves it open just like the default behaviour, but also allows application code to forcibly close the connection via a CloseConnection method.
Implementing ConnectionStrategy |
public class CloseableConnectionStrategy : ConnectionStrategy |
Using a Custom Connection Strategy
To use a custom connection strategy, set the UnitOfWork.ConnectionStrategy property to an instance of your custom strategy.
Using a custom connection strategy |
using (ModelUnitOfWork unitOfWork = _context.CreateUnitOfWork()) |
You must do this before the unit of work first connects to the database – otherwise the unit of work will use the default connection strategy. Do not change connection strategies in the middle of a unit of work. If desired, you can set up the connection strategy in the constructor of a strong‑typed unit of work, or through LightSpeedContext.UnitOfWorkFactory.
Note that the unit of work will not invoke any actions on your custom strategy other than to get connections and to notify various operations. It is up to application code to do this. For example, if you want to use the CloseableConnectionStrategy to close the connection after loading a screen, you might write something like this:
private void OnLoad() |
The connection is released, but the unit of work remains live, and will automatically reinitiate a connection when required – for example, if you load new entities, traverse an association, or call SaveChanges.
Note that some LightSpeed tasks, such as traversing an association, internally require a connection. Your connection strategy will still be used in such cases, but your application code may not be aware of it. For example, a data binding that traverses an association could cause your strategy to reinitiate a connection: this connection would remain open, and your application code would not know about it in order to reclaim it. If this is a concern, you can override ConnectionStrategy.OnDatabaseOperationComplete to receive notifications of LightSpeed database activity, but care is required that you do not close a connection while LightSpeed is still using it.