Files
gridpilot.gg/apps/website/lib/di-container.ts
2025-12-03 00:46:08 +01:00

187 lines
5.2 KiB
TypeScript

/**
* Dependency Injection Container
*
* Initializes all in-memory repositories and provides accessor functions.
* Allows easy swapping to persistent repositories later.
*/
import { Driver } from '../domain/entities/Driver';
import { League } from '../domain/entities/League';
import { Race } from '../domain/entities/Race';
import { Result } from '../domain/entities/Result';
import { Standing } from '../domain/entities/Standing';
import { IDriverRepository } from '../application/ports/IDriverRepository';
import { ILeagueRepository } from '../application/ports/ILeagueRepository';
import { IRaceRepository } from '../application/ports/IRaceRepository';
import { IResultRepository } from '../application/ports/IResultRepository';
import { IStandingRepository } from '../application/ports/IStandingRepository';
import { InMemoryDriverRepository } from '../infrastructure/repositories/InMemoryDriverRepository';
import { InMemoryLeagueRepository } from '../infrastructure/repositories/InMemoryLeagueRepository';
import { InMemoryRaceRepository } from '../infrastructure/repositories/InMemoryRaceRepository';
import { InMemoryResultRepository } from '../infrastructure/repositories/InMemoryResultRepository';
import { InMemoryStandingRepository } from '../infrastructure/repositories/InMemoryStandingRepository';
/**
* Seed data for development
*/
function createSeedData() {
// Create a sample driver
const driver1 = Driver.create({
id: '550e8400-e29b-41d4-a716-446655440001',
iracingId: '123456',
name: 'Max Verstappen',
country: 'NL',
bio: 'Three-time world champion',
joinedAt: new Date('2024-01-15'),
});
// Create a sample league
const league1 = League.create({
id: '550e8400-e29b-41d4-a716-446655440002',
name: 'European GT Championship',
description: 'Weekly GT3 racing with professional drivers',
ownerId: driver1.id,
settings: {
pointsSystem: 'f1-2024',
sessionDuration: 60,
qualifyingFormat: 'open',
},
createdAt: new Date('2024-01-20'),
});
// Create sample races
const race1 = Race.create({
id: '550e8400-e29b-41d4-a716-446655440003',
leagueId: league1.id,
scheduledAt: new Date('2024-03-15T19:00:00Z'),
track: 'Monza GP',
car: 'Porsche 911 GT3 R',
sessionType: 'race',
status: 'completed',
});
const race2 = Race.create({
id: '550e8400-e29b-41d4-a716-446655440004',
leagueId: league1.id,
scheduledAt: new Date('2024-03-22T19:00:00Z'),
track: 'Spa-Francorchamps',
car: 'Porsche 911 GT3 R',
sessionType: 'race',
status: 'scheduled',
});
return {
drivers: [driver1],
leagues: [league1],
races: [race1, race2],
};
}
/**
* DI Container class
*/
class DIContainer {
private static instance: DIContainer;
private _driverRepository: IDriverRepository;
private _leagueRepository: ILeagueRepository;
private _raceRepository: IRaceRepository;
private _resultRepository: IResultRepository;
private _standingRepository: IStandingRepository;
private constructor() {
// Create seed data
const seedData = createSeedData();
// Initialize repositories with seed data
this._driverRepository = new InMemoryDriverRepository(seedData.drivers);
this._leagueRepository = new InMemoryLeagueRepository(seedData.leagues);
this._raceRepository = new InMemoryRaceRepository(seedData.races);
// Result repository needs race repository for league-based queries
this._resultRepository = new InMemoryResultRepository(
undefined,
this._raceRepository
);
// Standing repository needs all three for recalculation
this._standingRepository = new InMemoryStandingRepository(
undefined,
this._resultRepository,
this._raceRepository,
this._leagueRepository
);
}
/**
* Get singleton instance
*/
static getInstance(): DIContainer {
if (!DIContainer.instance) {
DIContainer.instance = new DIContainer();
}
return DIContainer.instance;
}
/**
* Reset the container (useful for testing)
*/
static reset(): void {
DIContainer.instance = new DIContainer();
}
/**
* Repository getters
*/
get driverRepository(): IDriverRepository {
return this._driverRepository;
}
get leagueRepository(): ILeagueRepository {
return this._leagueRepository;
}
get raceRepository(): IRaceRepository {
return this._raceRepository;
}
get resultRepository(): IResultRepository {
return this._resultRepository;
}
get standingRepository(): IStandingRepository {
return this._standingRepository;
}
}
/**
* Exported accessor functions
*/
export function getDriverRepository(): IDriverRepository {
return DIContainer.getInstance().driverRepository;
}
export function getLeagueRepository(): ILeagueRepository {
return DIContainer.getInstance().leagueRepository;
}
export function getRaceRepository(): IRaceRepository {
return DIContainer.getInstance().raceRepository;
}
export function getResultRepository(): IResultRepository {
return DIContainer.getInstance().resultRepository;
}
export function getStandingRepository(): IStandingRepository {
return DIContainer.getInstance().standingRepository;
}
/**
* Reset function for testing
*/
export function resetContainer(): void {
DIContainer.reset();
}