Vue + TypeScript App architecture with autonomous service layer implementation
Goal: having an autonomous, central layer for the different services defined in their own modules that will provide all registered services through a custom hook
Step 1: in a new TypeScript file, import all needed services from their modules
```
import { Service1 } from '@/location1/Service1'
import { Service2 } from '@/location2/Service2'
import { Service3 } from '@/location3/Service3'
```
Step 2: define the object containing the services, so that we will be able to retrieve the services from it. New services will be imported and registered in this object. After that, extract its type for further need.
```
const services = {
service1: Service1,
service2: Service2
service3: Service3,
};
type AvailableServices = typeof services
```
Step 3: define a ServiceProvider class that will internally hold the services object
```
class ServiceProvider {
constructor(protected services: AvailableServices) {}
public provide( serviceName: keyof AvailableServices)
:InstanceType<AvailableServices[keyof AvailableServices]> {
return new this.services[serviceName]();
}
}
```
Note 1: constructor automatically initialising protected class member "services", no explicit initialiser needed
Note 2: the generic return type of the provide method. It creates the returned type instance based on the constructor function of the service returned
Step 4: create a service provider instance
```
const serviceProvider = new ServiceProvider(services);
```
Step 5: define the magic hook that we will be calling from all components for making use of the above defined logic
```
export function useService( serviceName: keyof AvailableServices,)
:InstanceType<AvailableServices[keyof AvailableServices]> {
return serviceProvider.provide(serviceName);
}
```
How to use it inside components:
```
import { useService } from '@/itsLocation';
const service1 = useService('service1');
```
Nice to have as a future implementation: each service as a singleton
Rares Raulea
03 Nov 2021
« Back to post