Custom Logger
Here we create the same counter as in the Simple Counter example, but our AbstractCounter
now takes an AbstractLogger
as constructor dependency.
Abstractions
The counter abstract class.
NOTA BENE
This is the same abstraction used in the Simple Counter example. We will now provide a new implementation, with the abstract logger as dependency.
export abstract class AbstractCounter {
public abstract increment(value: number): number;
public abstract decrement(value: number): number;
}
The logger abstract class.
export abstract class AbstractLogger {
public abstract log(...args: any[]): void;
public abstract info(...args: any[]): void;
public abstract warn(...args: any[]): void;
public abstract error(...args: any[]): void;
}
Services
We now have a new implementation of the counter's abstract class, that calls the log
method of the logger implementation we'll be using for the AbstractLogger
class.
import { Service } from 'diod';
import { AbstractLogger } from '../logger';
import { AbstractCounter } from './counter.abstract';
@Service()
export class Counter implements AbstractCounter {
// WARNING: Injected dependencies must be public.
constructor(public readonly logger: AbstractLogger) {}
public increment(value: number): number {
const count = value + 1;
this.logger.log(`In Counter: Count was %d and is now %d`, value, count);
return count;
}
public decrement(value: number): number {
const count = value - 1;
this.logger.log(`In Counter: Count was %d and is now %d`, value, count);
return count;
}
}
Application
// main.ts
import 'reflect-metadata';
import { createApp } from 'vue';
import VueDiod from 'vue-diod';
// Import abstractions.
import { AbstractCounter } from './counter.abstract';
import { AbstractLogger } from './logger.abstract';
// Import concrete classes.
import { Counter } from './counter.service';
import { Logger } from './logger.service';
import App from './App.vue';
const app = createApp(App);
app.use(VueDiod, {
injectables: [
{
register: AbstractCounter,
use: Counter,
},
// This one will be 'autowired' to Counter implementation above.
{
register: AbstractLogger,
use: Logger,
},
],
});
app.mount('#app');
Component
We can re-use our Simple Counter example component. The counter implementation's dependency is set at the application bootstrap.
<script setup lang="ts">
import type { Ref } from 'vue';
import { ref } from 'vue';
import { useVueDiod } from 'vue-diod';
import { AbstractCounter } from '../modules';
// Use the injection helper.
const { injectServiceInstance } = useVueDiod();
// Setup the (optional) fallback.
const fallback = () => {
return {
increment(value: number) {
console.warn('Function increment was called from fallback.');
return value++;
},
decrement(value: number) {
console.warn('Function decrement was called from fallback.');
return value--;
},
};
};
const counter = injectServiceInstance<AbstractCounter | any>(
AbstractCounter,
fallback
);
const count: Ref<number> = ref(0);
const increment = counter.increment.bind(counter);
const decrement = counter.decrement.bind(counter);
</script>
With the same template:
<template>
<button @click="increment(count)">Increment</button>
<button @click="decrement(count)">Decrement</button>
</template>
Result
ACTION REQUIRED
Open your devtools to see custom logs.
Logger
A logger component using the same injected dependency as our counter above.