yohira
v0.0.0-alpha.60
Published
Yohira is an experimental project to port ASP.NET Core to TypeScript.
Downloads
270
Readme
Yohira
Yohira is an experimental project to port ASP.NET Core to TypeScript.
Installation
npm i yohira
Dependency Injection
This is a TypeScript port of Microsoft.Extensions.DependencyInjection
.
Add interfaces
import { ServiceLifetime } from 'yohira';
interface IReportServiceLifetime {
readonly id: string;
readonly lifetime: ServiceLifetime;
}
const IExampleTransientService = Symbol.for('IExampleTransientService');
interface IExampleTransientService extends IReportServiceLifetime {
readonly lifetime: ServiceLifetime.Transient;
}
const IExampleScopedService = Symbol.for('IExampleScopedService');
interface IExampleScopedService extends IReportServiceLifetime {
readonly lifetime: ServiceLifetime.Scoped;
}
const IExampleSingletonService = Symbol.for('IExampleSingletonService');
interface IExampleSingletonService extends IReportServiceLifetime {
readonly lifetime: ServiceLifetime.Singleton;
}
Add default implementations
import { randomUUID } from 'node:crypto';
class ExampleTransientService implements IExampleTransientService {
readonly id = randomUUID();
readonly lifetime = ServiceLifetime.Transient;
}
class ExampleScopedService implements IExampleScopedService {
readonly id = randomUUID();
readonly lifetime = ServiceLifetime.Scoped;
}
class ExampleSingletonService implements IExampleSingletonService {
readonly id = randomUUID();
readonly lifetime = ServiceLifetime.Singleton;
}
Add a service that requires DI
import { inject } from 'yohira';
function logService<T extends IReportServiceLifetime>(
name: symbol,
service: T,
message: string,
): void {
console.log(` ${Symbol.keyFor(name)}: ${service.id} (${message})`);
}
class ServiceLifetimeReporter {
constructor(
@inject(IExampleTransientService)
private readonly transientService: IExampleTransientService,
@inject(IExampleScopedService)
private readonly scopedService: IExampleScopedService,
@inject(IExampleSingletonService)
private readonly singletonService: IExampleSingletonService,
) {}
reportServiceLifetimeDetails(lifetimeDetails: string): void {
console.log(lifetimeDetails);
logService(
IExampleTransientService,
this.transientService,
'Always different',
);
logService(
IExampleScopedService,
this.scopedService,
'Changes only with lifetime',
);
logService(
IExampleSingletonService,
this.singletonService,
'Always the same',
);
}
}
Register services for DI
import {
IServiceProvider,
addScopedCtor,
addSingletonCtor,
addTransientCtor,
createDefaultBuilder,
createScope,
getRequiredService,
runApp,
} from 'yohira';
function exemplifyServiceLifetime(
hostProvider: IServiceProvider,
lifetime: string,
): void {
const serviceScope = createScope(hostProvider);
const provider = serviceScope.serviceProvider;
const reporter1 = getRequiredService<ServiceLifetimeReporter>(
provider,
Symbol.for('ServiceLifetimeReporter'),
);
reporter1.reportServiceLifetimeDetails(
`${lifetime}: Call 1 to getRequiredService<ServiceLifetimeReporter>` +
"(provider, Symbol.for('ServiceLifetimeReporter'))",
);
console.log('...');
const reporter2 = getRequiredService<ServiceLifetimeReporter>(
provider,
Symbol.for('ServiceLifetimeReporter'),
);
reporter2.reportServiceLifetimeDetails(
`${lifetime}: Call 2 to getRequiredService<ServiceLifetimeReporter>` +
"(provider, Symbol.for('ServiceLifetimeReporter'))",
);
console.log('\n');
serviceScope.dispose();
}
const host = createDefaultBuilder()
.configureServices((context, services) => {
addTransientCtor(
services,
IExampleTransientService,
ExampleTransientService,
);
addScopedCtor(services, IExampleScopedService, ExampleScopedService);
addSingletonCtor(
services,
IExampleSingletonService,
ExampleSingletonService,
);
addTransientCtor(
services,
Symbol.for('ServiceLifetimeReporter'),
ServiceLifetimeReporter,
);
})
.build();
exemplifyServiceLifetime(host.services, 'Lifetime 1');
exemplifyServiceLifetime(host.services, 'Lifetime 2');
await runApp(host);
See also
References
- dotnet/aspnetcore: ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
- Deep Dive: How is the ASP.NET Core Middleware Pipeline Built? - Steve Gordon - Code with Steve
- ASP.NET Core Anatomy - How does UseStartup work? - Steve Gordon - Code with Steve
- Styles of Writing ASP.NET Core Middleware
- Writing convention-based ASP.NET Core middleware - part 3
- Writing factory-based ASP.NET Core middleware - part 4
- koajs/koa: Expressive middleware for node.js using ES2017 async functions
- asp.net core - What is the difference between IWebHost WebHostBuilder BuildWebHost - Stack Overflow
- .NET Generic Host - .NET | Microsoft Learn
- aspnetcore/BuildFromSource.md at 6956f42a0a01ed4fb8fc2cb889c2535f8fe5f735 · dotnet/aspnetcore
- ASP.NET Core Dependency Injection: What is the IServiceCollection? - Steve Gordon - Code with Steve
- ASP.NET Core Dependency Injection: What is the IServiceProvider and how is it Built? - Steve Gordon - Code with Steve
- Dependency injection - .NET | Microsoft Learn
- Worker Services - .NET | Microsoft Learn
- Dependency injection guidelines - .NET | Microsoft Learn
- Strongly Typed Configuration Settings in ASP.NET Core - Rick Strahl's Web Log
- Easy Configuration Binding in ASP.NET Core - revisited - Rick Strahl's Web Log
- Routing in ASP.NET Core | Microsoft Learn
- Why doesn't IConfigurationProvider have an async Load method? · Issue #36018 · dotnet/runtime
- [API Proposal]: AsyncConfigurationProvider · Issue #79193 · dotnet/runtime
- c# - What's the role of the ClaimsPrincipal, why does it have multiple Identities? - Stack Overflow
- Session in ASP.NET Core | Microsoft Learn
- Key storage format in ASP.NET Core | Microsoft Learn
- Key management extensibility in ASP.NET Core | Microsoft Learn
- Use cookie authentication without ASP.NET Core Identity | Microsoft Learn
- Mapping, customizing, and transforming claims in ASP.NET Core | Microsoft Learn