diff --git a/src/app/core/components/core-abstract/core-abstract.component.ts b/src/app/core/components/core-abstract/core-abstract.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1ff3c1c59d4522014ce23515315c93091796a265
--- /dev/null
+++ b/src/app/core/components/core-abstract/core-abstract.component.ts
@@ -0,0 +1,5 @@
+import {CoreAbstractAngularElement} from "@app/core/models/angular/core-abstract-angular-element.model";
+
+export class CoreAbstractComponent extends CoreAbstractAngularElement {
+
+}
diff --git a/src/app/core/directives/core-abstract/core-abstract.directive.ts b/src/app/core/directives/core-abstract/core-abstract.directive.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8e5c97c7b6ba866a0ae12472001bbefc88f6c4ee
--- /dev/null
+++ b/src/app/core/directives/core-abstract/core-abstract.directive.ts
@@ -0,0 +1,5 @@
+import {CoreAbstractAngularElement} from "@app/core/models/angular/core-abstract-angular-element.model";
+
+export class CoreAbstractDirective extends CoreAbstractAngularElement {
+
+}
diff --git a/src/app/core/models/angular/core-abstract-angular-element.model.ts b/src/app/core/models/angular/core-abstract-angular-element.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..09f466db4ad474d4d52a92fce1ab86a875d469a7
--- /dev/null
+++ b/src/app/core/models/angular/core-abstract-angular-element.model.ts
@@ -0,0 +1,209 @@
+import {
+  AfterContentChecked,
+  AfterContentInit,
+  AfterViewChecked,
+  AfterViewInit,
+  ChangeDetectorRef,
+  DoCheck,
+  EventEmitter,
+  OnChanges,
+  OnDestroy,
+  OnInit,
+  SimpleChanges,
+} from "@angular/core";
+import {SubscriptionManager} from "@app/core/models/managers/subscription-manager.model";
+import {CounterSubject} from "@app/core/models/observables/counter-subject.model";
+import {isFunction, isTruthyObject} from "@app/core/tools/is/is.tool";
+import {Observable, Subscription} from "rxjs";
+
+export class CoreAbstractAngularElement implements OnChanges, OnInit, DoCheck, AfterContentInit, AfterContentChecked, AfterViewInit, AfterViewChecked, OnDestroy {
+
+  /* Subscription manager */
+
+  protected readonly _subscriptionManager: SubscriptionManager = new SubscriptionManager();
+
+  /* Angular state */
+
+  get changed(): boolean {
+    return this._ngOnChangesCS.hasCount();
+  }
+
+  get changesCount(): number {
+    return this._ngOnChangesCS.getValue();
+  }
+
+  private _initialized: boolean = false;
+
+  get initialized(): boolean {
+    return this._initialized;
+  }
+
+  get checked(): boolean {
+    return this._ngDoCheckCS.hasCount();
+  }
+
+  get checksCount(): number {
+    return this._ngDoCheckCS.getValue();
+  }
+
+  private _contentInitialized: boolean = false;
+
+  get contentInitialized(): boolean {
+    return this._contentInitialized;
+  }
+
+  get contentChecked(): boolean {
+    return this._ngAfterContentCheckedCS.hasCount();
+  }
+
+  get contentChecksCount(): number {
+    return this._ngAfterContentCheckedCS.getValue();
+  }
+
+  private _viewInitialized: boolean = false;
+
+  get viewInitialized(): boolean {
+    return this._viewInitialized;
+  }
+
+  get viewChecked(): boolean {
+    return this._ngAfterViewCheckedCS.hasCount();
+  }
+
+  get viewChecksCount(): number {
+    return this._ngAfterViewCheckedCS.getValue();
+  }
+
+  private _destroyed: boolean = false;
+
+  get destroyed(): boolean {
+    return this._destroyed;
+  }
+
+  /* Angular frequent lifecycle hooks counter subjects */
+
+  private readonly _ngOnChangesCS: CounterSubject = new CounterSubject();
+
+  private readonly _ngDoCheckCS: CounterSubject = new CounterSubject();
+
+  private readonly _ngAfterContentCheckedCS: CounterSubject = new CounterSubject();
+
+  private readonly _ngAfterViewCheckedCS: CounterSubject = new CounterSubject();
+
+  /* Angular occasional lifecycle hooks event emitters */
+
+  private readonly _ngOnInitEventEmitter: EventEmitter<boolean> = new EventEmitter<boolean>();
+
+  private readonly _ngAfterContentInitEventEmitter: EventEmitter<boolean> = new EventEmitter<boolean>();
+
+  private readonly _ngAfterViewInitEventEmitter: EventEmitter<boolean> = new EventEmitter<boolean>();
+
+  private readonly _ngOnDestroyEventEmitter: EventEmitter<boolean> = new EventEmitter<boolean>();
+
+  /* Angular lifecycle hooks value event emitters */
+
+  private readonly _ngOnChangesValueEventEmitter: EventEmitter<SimpleChanges> = new EventEmitter<SimpleChanges>();
+
+  /* Angular lifecycle hooks base implementation */
+
+  ngOnChanges(changes: SimpleChanges): void {
+    // Fix ngOnInit
+    if (this.changed && !this.initialized) {
+      this.ngOnInit();
+    }
+    this._ngOnChangesValueEventEmitter.emit(changes);
+    this._ngOnChangesCS.increment();
+  }
+
+  ngOnInit(): void {
+    if (!this._initialized) {
+      this._initialized = true;
+      this._ngOnInitEventEmitter.emit(true);
+    } else {
+      this._ngOnInitEventEmitter.emit(false);
+    }
+  }
+
+  ngDoCheck(): void {
+    this._ngDoCheckCS.increment();
+  }
+
+  ngAfterContentInit(): void {
+    if (!this._contentInitialized) {
+      this._contentInitialized = true;
+      this._ngAfterContentInitEventEmitter.emit(true);
+    } else {
+      this._ngAfterContentInitEventEmitter.emit(false);
+    }
+  }
+
+  ngAfterContentChecked(): void {
+    this._ngAfterContentCheckedCS.increment();
+  }
+
+  ngAfterViewInit(): void {
+    if (!this._viewInitialized) {
+      this._viewInitialized = true;
+      this._ngAfterViewInitEventEmitter.emit(true);
+    } else {
+      this._ngAfterViewInitEventEmitter.emit(false);
+    }
+  }
+
+  ngAfterViewChecked(): void {
+    this._ngAfterViewCheckedCS.increment();
+  }
+
+  ngOnDestroy(): void {
+    if (!this._destroyed) {
+      this._destroyed = true;
+      this._ngOnDestroyEventEmitter.emit(true);
+    } else {
+      this._ngOnDestroyEventEmitter.emit(false);
+    }
+    this._subscriptionManager.clearAndUnsubscribeAll();
+  }
+
+  /* Angular lifecycle hooks observables */
+
+  readonly ngOnChangesObs: Observable<number> = this._ngOnChangesCS.asObservable();
+
+  readonly ngOnChangesValueObs: Observable<SimpleChanges> = this._ngOnChangesValueEventEmitter.asObservable();
+
+  readonly ngOnInitObs: Observable<boolean> = this._ngOnInitEventEmitter.asObservable();
+
+  readonly ngDoCheckObs: Observable<number> = this._ngDoCheckCS.asObservable();
+
+  readonly ngAfterContentInitObs: Observable<boolean> = this._ngAfterContentInitEventEmitter.asObservable();
+
+  readonly ngAfterContentCheckedObs: Observable<number> = this._ngAfterContentCheckedCS.asObservable();
+
+  readonly ngAfterViewInitObs: Observable<boolean> = this._ngAfterViewInitEventEmitter.asObservable();
+
+  readonly ngAfterViewCheckedObs: Observable<number> = this._ngAfterViewCheckedCS.asObservable();
+
+  readonly ngOnDestroyObs: Observable<boolean> = this._ngOnDestroyEventEmitter.asObservable();
+
+  /* Detect changes */
+
+  detectChanges(changeDetectorRef: ChangeDetectorRef): boolean {
+    if (this.initialized
+      && !this.destroyed
+      && isTruthyObject(changeDetectorRef)
+      && isFunction(changeDetectorRef.detectChanges)) {
+      changeDetectorRef.detectChanges();
+      return true;
+    }
+    return false;
+  }
+
+  /* Subscribe */
+
+  subscribe<T>(observable: Observable<T>,
+               onNext?: (value: T) => void,
+               onError?: (error: Error) => void,
+               onComplete?: () => void): Subscription {
+    return this._subscriptionManager.subscribe(observable, onNext, onError, onComplete);
+  }
+
+}
diff --git a/src/app/core/models/managers/subscription-manager.model.ts b/src/app/core/models/managers/subscription-manager.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..714d9ff50cfde4e70e096ba34442313d0441bb29
--- /dev/null
+++ b/src/app/core/models/managers/subscription-manager.model.ts
@@ -0,0 +1,58 @@
+import {SubscriptionUtil} from "@app/core/utils/subscription.util";
+import {Observable, Subscription} from "rxjs";
+
+export class SubscriptionManager {
+
+  private readonly _subscriptions: Subscription[] = [];
+
+  geSubscriptions(): Subscription[] {
+    return this._subscriptions.slice();
+  }
+
+  subscribe<T>(observable: Observable<T>,
+               onNext?: (value: T) => void,
+               onError?: (error: Error) => void,
+               onComplete?: () => void): Subscription {
+    const subscription = observable.subscribe(onNext, onError, onComplete);
+    this.add(subscription);
+    return subscription;
+  }
+
+  add(subscription: Subscription): boolean {
+    if (SubscriptionUtil.isUnsubscribable(subscription)) {
+      this._subscriptions.push(subscription);
+      return true;
+    }
+    return false;
+  }
+
+  addMultiple(...subscriptions: Subscription[]): number {
+    return subscriptions.reduce((seed, next) => seed + (this.add(next) ? 1 : 0), 0);
+  }
+
+  remove(subscription: Subscription): boolean {
+    const index = this._subscriptions.indexOf(subscription);
+    if (index < 0) {
+      return false;
+    }
+    this._subscriptions.splice(index, 1);
+    return true;
+  }
+
+  clear(): boolean {
+    if (this._subscriptions.length === 0) {
+      return false;
+    }
+    this._subscriptions.splice(0);
+    return true;
+  }
+
+  removeAndUnsubscribe(subscription: Subscription): boolean {
+    return this.remove(subscription) && SubscriptionUtil.unsubscribe(subscription);
+  }
+
+  clearAndUnsubscribeAll(): number {
+    return this._subscriptions.splice(0).reduce((seed, next) => seed + (SubscriptionUtil.unsubscribe(next) ? 1 : 0), 0);
+  }
+
+}
diff --git a/src/app/core/models/observables/counter-subject.model.ts b/src/app/core/models/observables/counter-subject.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3090817fa648edbd5c7054eb3b6af8a57b1bd22e
--- /dev/null
+++ b/src/app/core/models/observables/counter-subject.model.ts
@@ -0,0 +1,34 @@
+import {isNumberReal} from "@app/core/tools/is/is.tool";
+import {BehaviorSubject} from "rxjs";
+
+export class CounterSubject extends BehaviorSubject<number> {
+
+  private static _toSafeValue(value: any): number {
+    return isNumberReal(value) && value >= 0 ? value : 0;
+  }
+
+  constructor(initialCount: number = 0) {
+    super(CounterSubject._toSafeValue(initialCount));
+  }
+
+  next(count: any): void {
+    super.next(CounterSubject._toSafeValue(parseFloat(count)));
+  }
+
+  hasCount(): boolean {
+    return this.getValue() > 0;
+  }
+
+  increment(increment: number = 1): number {
+    const result = this.getValue() + parseFloat(increment as any);
+    this.next(result);
+    return result;
+  }
+
+  decrement(decrement: number = 1): number {
+    const result = this.getValue() - parseFloat(decrement as any);
+    this.next(result);
+    return result;
+  }
+
+}
diff --git a/src/app/core/pipes/core-abstract/core-abstract.pipe.ts b/src/app/core/pipes/core-abstract/core-abstract.pipe.ts
new file mode 100644
index 0000000000000000000000000000000000000000..276b756a5a5d0e388d83a7d97e0934160a80f8ff
--- /dev/null
+++ b/src/app/core/pipes/core-abstract/core-abstract.pipe.ts
@@ -0,0 +1,5 @@
+import {CoreAbstractAngularElement} from "@app/core/models/angular/core-abstract-angular-element.model";
+
+export class CoreAbstractPipe extends CoreAbstractAngularElement {
+
+}
diff --git a/src/app/shared/tools/is.tool.ts b/src/app/core/tools/is/is.tool.ts
similarity index 100%
rename from src/app/shared/tools/is.tool.ts
rename to src/app/core/tools/is/is.tool.ts
diff --git a/src/app/core/utils/subscription.util.ts b/src/app/core/utils/subscription.util.ts
new file mode 100644
index 0000000000000000000000000000000000000000..eb17a7f66beeba9a7945d6537cd49440047b112e
--- /dev/null
+++ b/src/app/core/utils/subscription.util.ts
@@ -0,0 +1,18 @@
+import {isFunction, isReference, isTruthy} from "@app/core/tools/is/is.tool";
+import {Subscription} from "rxjs";
+
+export class SubscriptionUtil {
+
+  static isUnsubscribable(subscription: Subscription): boolean {
+    return isReference(subscription) && isFunction(subscription.unsubscribe) && !subscription.closed;
+  }
+
+  static unsubscribe(subscription: Subscription): boolean {
+    if (this.isUnsubscribable(subscription)) {
+      subscription.unsubscribe();
+      return isTruthy(subscription.closed);
+    }
+    return false;
+  }
+
+}
diff --git a/src/app/shared/components/abstract/abstract.component.ts b/src/app/shared/components/abstract/abstract.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..fb932b30f7b401f99ba42225e795eea827ca1065
--- /dev/null
+++ b/src/app/shared/components/abstract/abstract.component.ts
@@ -0,0 +1,5 @@
+import {CoreAbstractComponent} from "@app/core/components/core-abstract/core-abstract.component";
+
+export class AbstractComponent extends CoreAbstractComponent {
+
+}
diff --git a/src/app/shared/directives/abstract/abstract.directive.ts b/src/app/shared/directives/abstract/abstract.directive.ts
new file mode 100644
index 0000000000000000000000000000000000000000..63bb248a2e1a3a24a2090aef9ba259ac03954481
--- /dev/null
+++ b/src/app/shared/directives/abstract/abstract.directive.ts
@@ -0,0 +1,5 @@
+import {CoreAbstractDirective} from "@app/core/directives/core-abstract/core-abstract.directive";
+
+export class AbstractDirective extends CoreAbstractDirective {
+
+}
diff --git a/src/app/shared/directives/base.directive.ts b/src/app/shared/directives/base.directive.ts
index bfe63878dcd3363b3bfec1f0939e7ec061840fea..5a56a13b4e65f0f4bba9a620163daeefaaf2b3bc 100644
--- a/src/app/shared/directives/base.directive.ts
+++ b/src/app/shared/directives/base.directive.ts
@@ -16,7 +16,7 @@ export abstract class BaseDirective implements OnDestroy {
     });
   }
 
-  addToSubscription(subscription: Subscription) {
+  addToSubscription(subscription: Subscription): void {
     this.listSubscription.push(subscription);
   }
 }
diff --git a/src/app/shared/pipes/abstract/abstract.pipe.ts b/src/app/shared/pipes/abstract/abstract.pipe.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d5601775df48f7e6c238fda2213800417cc7b641
--- /dev/null
+++ b/src/app/shared/pipes/abstract/abstract.pipe.ts
@@ -0,0 +1,5 @@
+import {CoreAbstractPipe} from "@app/core/pipes/core-abstract/core-abstract.pipe";
+
+export class AbstractPipe extends CoreAbstractPipe {
+
+}
diff --git a/src/app/shared/pipes/is-pipes/is-boolean.pipe.ts b/src/app/shared/pipes/is-pipes/is-boolean.pipe.ts
index 474514e7b34f4e71d97df01a6c7d133f7192f2dd..f108e148cdd1e870b9ebfcac04cffd8110275a7c 100644
--- a/src/app/shared/pipes/is-pipes/is-boolean.pipe.ts
+++ b/src/app/shared/pipes/is-pipes/is-boolean.pipe.ts
@@ -1,6 +1,6 @@
 import {Pipe, PipeTransform} from "@angular/core";
 
-import {isBoolean} from "@app/shared/tools/is.tool";
+import {isBoolean} from "@app/core/tools/is/is.tool";
 
 @Pipe({
   name: "isBoolean",
diff --git a/src/app/shared/pipes/is-pipes/is-false.pipe.ts b/src/app/shared/pipes/is-pipes/is-false.pipe.ts
index c80f8c776072a0dd37fe60ebde92c37c4c8bb3cc..54bf6c83c2b361fed69ca89c5732f18e2f81ace3 100644
--- a/src/app/shared/pipes/is-pipes/is-false.pipe.ts
+++ b/src/app/shared/pipes/is-pipes/is-false.pipe.ts
@@ -1,6 +1,6 @@
 import {Pipe, PipeTransform} from "@angular/core";
 
-import {isFalse} from "@app/shared/tools/is.tool";
+import {isFalse} from "@app/core/tools/is/is.tool";
 
 @Pipe({
   name: "isFalse",
diff --git a/src/app/shared/pipes/is-pipes/is-function.pipe.ts b/src/app/shared/pipes/is-pipes/is-function.pipe.ts
index fc27d7da8fa719b29a94ff476456f346ba109518..d3acb362da3693af9343cdc3f565b986d4f5535a 100644
--- a/src/app/shared/pipes/is-pipes/is-function.pipe.ts
+++ b/src/app/shared/pipes/is-pipes/is-function.pipe.ts
@@ -1,6 +1,6 @@
 import {Pipe, PipeTransform} from "@angular/core";
 
-import {isBoolean, isFunction} from "@app/shared/tools/is.tool";
+import {isBoolean, isFunction} from "@app/core/tools/is/is.tool";
 
 @Pipe({
   name: "isFunction",
diff --git a/src/app/shared/pipes/is-pipes/is-number-finite.pipe.ts b/src/app/shared/pipes/is-pipes/is-number-finite.pipe.ts
index 544716e4e13835a8d75a0fced86ff68c63b3a48a..a925b06e4bbe1502dd7dd4b85d63f570bb3f5cb6 100644
--- a/src/app/shared/pipes/is-pipes/is-number-finite.pipe.ts
+++ b/src/app/shared/pipes/is-pipes/is-number-finite.pipe.ts
@@ -1,6 +1,6 @@
 import {Pipe, PipeTransform} from "@angular/core";
 
-import {isBoolean, isNumberFinite} from "@app/shared/tools/is.tool";
+import {isBoolean, isNumberFinite} from "@app/core/tools/is/is.tool";
 
 @Pipe({
   name: "isNumberFinite",
diff --git a/src/app/shared/pipes/is-pipes/is-number-invalid.pipe.ts b/src/app/shared/pipes/is-pipes/is-number-invalid.pipe.ts
index 83f616dd3f53687301878bbd3feb055859af4daa..812be1ef26330157840ba054337273f833318e73 100644
--- a/src/app/shared/pipes/is-pipes/is-number-invalid.pipe.ts
+++ b/src/app/shared/pipes/is-pipes/is-number-invalid.pipe.ts
@@ -1,6 +1,6 @@
 import {Pipe, PipeTransform} from "@angular/core";
 
-import {isBoolean, isNumberInvalid} from "@app/shared/tools/is.tool";
+import {isBoolean, isNumberInvalid} from "@app/core/tools/is/is.tool";
 
 @Pipe({
   name: "isNumberInvalid",
diff --git a/src/app/shared/pipes/is-pipes/is-number-valid.pipe.ts b/src/app/shared/pipes/is-pipes/is-number-valid.pipe.ts
index ceeb0308b3e9a879ff0a93c7de5ba52d32853561..01332171e4370f1d7a92abcd05900e9c5f234ac9 100644
--- a/src/app/shared/pipes/is-pipes/is-number-valid.pipe.ts
+++ b/src/app/shared/pipes/is-pipes/is-number-valid.pipe.ts
@@ -1,6 +1,6 @@
 import {Pipe, PipeTransform} from "@angular/core";
 
-import {isBoolean, isNumberValid} from "@app/shared/tools/is.tool";
+import {isBoolean, isNumberValid} from "@app/core/tools/is/is.tool";
 
 @Pipe({
   name: "isNumberValid",
diff --git a/src/app/shared/pipes/is-pipes/is-number.pipe.ts b/src/app/shared/pipes/is-pipes/is-number.pipe.ts
index b1c748cf0a4761c4bef4e288e33604ff29d4006c..8caaf3154dd68b30777be282f0b890a8d75d2e82 100644
--- a/src/app/shared/pipes/is-pipes/is-number.pipe.ts
+++ b/src/app/shared/pipes/is-pipes/is-number.pipe.ts
@@ -1,6 +1,6 @@
 import {Pipe, PipeTransform} from "@angular/core";
 
-import {isBoolean, isNumber} from "@app/shared/tools/is.tool";
+import {isBoolean, isNumber} from "@app/core/tools/is/is.tool";
 
 @Pipe({
   name: "isNumber",
diff --git a/src/app/shared/pipes/is-pipes/is-true.pipe.ts b/src/app/shared/pipes/is-pipes/is-true.pipe.ts
index adcdf9cc46f84888202ba4ba3888b8e649f3f678..fd80a1f6bb9bdd57f405683960e6bae1538bc802 100644
--- a/src/app/shared/pipes/is-pipes/is-true.pipe.ts
+++ b/src/app/shared/pipes/is-pipes/is-true.pipe.ts
@@ -1,6 +1,6 @@
 import {Pipe, PipeTransform} from "@angular/core";
 
-import {isBoolean, isTrue} from "@app/shared/tools/is.tool";
+import {isBoolean, isTrue} from "@app/core/tools/is/is.tool";
 
 @Pipe({
   name: "isTrue",
diff --git a/src/app/shared/pipes/is-pipes/is-truthy-object.pipe.ts b/src/app/shared/pipes/is-pipes/is-truthy-object.pipe.ts
index e4745edc199bb25de7c0299deab2744144c3aa51..0d8e97f31684c78816e518c4d99b1dea17f255b0 100644
--- a/src/app/shared/pipes/is-pipes/is-truthy-object.pipe.ts
+++ b/src/app/shared/pipes/is-pipes/is-truthy-object.pipe.ts
@@ -1,6 +1,6 @@
 import {Pipe, PipeTransform} from "@angular/core";
 
-import {isTruthyObject} from "@app/shared/tools/is.tool";
+import {isTruthyObject} from "@app/core/tools/is/is.tool";
 
 @Pipe({
   name: "isTruthyObject",
diff --git a/src/app/shared/pipes/is-pipes/is-truthy.pipe.ts b/src/app/shared/pipes/is-pipes/is-truthy.pipe.ts
index 9c0b3815faedfdd76098367a5c03ab59e5eb67c0..430a37bd9170f00ad3915ea0bc6b152790ad34b1 100644
--- a/src/app/shared/pipes/is-pipes/is-truthy.pipe.ts
+++ b/src/app/shared/pipes/is-pipes/is-truthy.pipe.ts
@@ -1,6 +1,6 @@
 import {Pipe, PipeTransform} from "@angular/core";
 
-import {isBoolean, isTruthy} from "@app/shared/tools/is.tool";
+import {isBoolean, isTruthy} from "@app/core/tools/is/is.tool";
 
 @Pipe({
   name: "isTruthy",
diff --git a/src/app/shared/utils/solidify-metadata.util.ts b/src/app/shared/utils/solidify-metadata.util.ts
index 28757fb92d62f82589b5a14dc1365db7908092e5..516791d146de077660fcc6e4b5310ae91f0c7c50 100644
--- a/src/app/shared/utils/solidify-metadata.util.ts
+++ b/src/app/shared/utils/solidify-metadata.util.ts
@@ -1,5 +1,5 @@
+import {isTruthyObject} from "@app/core/tools/is/is.tool";
 import {RegisteredCrudAction} from "@app/shared/decorators/crud.decorator";
-import {isUndefined} from "@app/shared/tools/is.tool";
 
 export const SOLIDIFY_META_KEY = "SOLIDIFY_META";
 
@@ -19,7 +19,7 @@ export class SolidifyMetadataUtil {
    * Ensures metadata is attached to the class and returns it.
    */
   static ensureStoreSolidifyMetadata(target: SolidifyStateClass): SolidifyMetaDataModel {
-    if (isUndefined(target[SOLIDIFY_META_KEY] === undefined)) {
+    if (!isTruthyObject(target[SOLIDIFY_META_KEY])) {
       target[SOLIDIFY_META_KEY] = {};
     }
     return target[SOLIDIFY_META_KEY];
diff --git a/src/app/shared/views/abstract-detail/abstract-detail.view.ts b/src/app/shared/views/abstract-detail/abstract-detail.view.ts
index 8f5573699c299164bf72ec26e395649a8af75963..c10827180a9952ab2231f58be5fb870f2b4ab861 100644
--- a/src/app/shared/views/abstract-detail/abstract-detail.view.ts
+++ b/src/app/shared/views/abstract-detail/abstract-detail.view.ts
@@ -2,10 +2,10 @@ import {ComponentType} from "@angular/cdk/portal";
 import {OnInit} from "@angular/core";
 import {MatDialog} from "@angular/material";
 import {ActivatedRoute} from "@angular/router";
+import {AbstractComponent} from "@app/shared/components/abstract/abstract.component";
 import {CrudNameSpace} from "@app/shared/crud.namespace";
 import {CrudStateModel} from "@app/shared/crud.state";
 import {AbstractDeleteDialog} from "@app/shared/dialogs/abstract-delete/abstract-delete.dialog";
-import {BaseDirective} from "@app/shared/directives/base.directive";
 import {ModelAttributeEnum} from "@app/shared/enums/model-attribute.enum";
 import {StateEnum} from "@app/shared/enums/state.enum";
 import {DeleteDialogModel} from "@app/shared/models/delete-dialog.model";
@@ -17,7 +17,7 @@ import {Store} from "@ngxs/store";
 import {Observable} from "rxjs";
 import {take} from "rxjs/operators";
 
-export abstract class AbstractDetailView<T, U extends CrudStateModel<T>> extends BaseDirective implements OnInit {
+export abstract class AbstractDetailView<T, U extends CrudStateModel<T>> extends AbstractComponent implements OnInit {
 
   isLoading$: Observable<boolean>;
   current$: Observable<T>;
@@ -39,6 +39,7 @@ export abstract class AbstractDetailView<T, U extends CrudStateModel<T>> extends
   }
 
   ngOnInit(): void {
+    super.ngOnInit();
     this.store.dispatch(CrudActionUtil.loadResource(this.crudActionNameSpace));
     this.retreiveCurrentModelWithUrl();
   }
@@ -65,10 +66,12 @@ export abstract class AbstractDetailView<T, U extends CrudStateModel<T>> extends
 
   delete() {
     const datas = {} as DeleteDialogModel;
-    this.addToSubscription(this.current$.pipe(take(1)).subscribe((model: T) => {
-      datas.name = model[this.KEY_PARAM_NAME];
-      datas.resId = model[ModelAttributeEnum.resId];
-    }));
+    this.subscribe(
+      this.current$.pipe(take(1)),
+      (model: T) => {
+        datas.name = model[this.KEY_PARAM_NAME];
+        datas.resId = model[ModelAttributeEnum.resId];
+      });
     const dialogRef = this.dialog.open(CrudDialogUtil.delete(this.state) as ComponentType<AbstractDeleteDialog<T, U>>, {
       width: "250px",
       data: datas,