Disposable abstract class
npm i disposable-class
import { disposable } from 'disposable-class';
interface DbConnection {
close(): void;
}
@disposable
class Repository {
private _conn: DbConnection;
constructor(conn: DbConnection) {
this._conn = conn;
}
public dispose(): void {
// with decorator you do not have to call super.dispose();
// the decorator does it automatically
this._conn.close();
}
}
import { Disposable } from 'disposable-class';
interface DbConnection {
close(): void;
}
class Repository extends Disposable {
private _conn: DbConnection;
constructor(conn: DbConnection) {
super();
this._conn = conn;
}
public dispose(): void {
if (!this.isDisposed()) {
// important to call in order to mark the class as disposed
super.dispose();
this._conn.close();
}
}
}
import { disposable, free } from 'disposable-class';
@disposable
class Repository {
@free()
private _data: []; // the property will be dereferenced
constructor() {
this._conn = [];
}
}
import { disposable, free } from 'disposable-class';
@disposable
class ResourceA {
@free()
private _data: []; // the property will be dereferenced
constructor() {
this._conn = [];
}
}
@disposable
class ResourceB {
@free()
private _data: ResourceA; // 'dispose' will be invoked and the property will be dereferenced
constructor() {
this._conn = new ResourceA();
}
}
import { disposable, free } from 'disposable-class';
interface DbConnection {
close(): void;
}
@disposable
class Repository {
// "free" decorator allows you to create an alias for a property
// by adding information what method must be called to free underlying resource.
// Optionally, 'check' param can be passed in order to do a check whether the resource needs to be freed.
// For example, "@free({ call: 'close', check: 'isClosed' })".
@free({ call: 'close' })
private _conn: { close: Function };
constructor(conn: DbConnection) {
this._conn = conn;
}
}
import { disposable, free } from 'disposable-class';
interface DbConnection {
close(): void;
isClosed(): boolean;
}
@disposable
class Repository {
// You can go wild
@free({
call: (conn: DbConnection) => conn.close(),
check: (conn: DbConnection) => conn.isClosed(),
})
private _conn: DbConnection;
constructor(conn: DbConnection) {
this._conn = conn;
}
}
import { disposable, free, protect } from 'disposable-class';
@disposable
class List<T> {
@free()
private _items: T[];
constructor() {
this._items = [];
}
// Onсe the instance gets disposed
// All further function calls will be ignored and DisposedError will be thrown
@protect()
public add(item: T): void {
// It's very important to protect methods that use properties that marked as freeable
// In order to avoid runtime error, because the properties will be derefferenced
this._items.push(item);
}
}
import { disposable, protect } from 'disposable-class';
@disposable
class Repository {
@free()
private _conn: DbConnection;
constructor(conn: DbConnection) {
this._conn = conn;
}
// Once the instance gets disposed
// All further function calls will return rejected Promise
@protect({ async: true })
public async findOne(query: any): void {
return this._conn.findOne(query);
}
}