- Add comprehensive error handling system with custom error pages - Implement professional enterprise-style design with Tailwind CSS - Create modular HMVC architecture with clean separation of concerns - Add security features: CSRF protection, XSS filtering, Argon2ID hashing - Include CLI tools for development workflow - Add error reporting dashboard with system monitoring - Implement responsive design with consistent slate color scheme - Replace all emoji icons with professional SVG icons - Add comprehensive test suite with PHPUnit - Include database migrations and seeders - Add proper exception handling with fallback pages - Implement template engine with custom syntax support - Add helper functions and facades for clean code - Include proper logging and debugging capabilities
129 lines
3.3 KiB
PHP
129 lines
3.3 KiB
PHP
<?php
|
|
|
|
namespace App\Core;
|
|
|
|
/**
|
|
* NovaCore Dependency Injection Container
|
|
* Simple service container
|
|
*/
|
|
class Container
|
|
{
|
|
private array $services = [];
|
|
private array $singletons = [];
|
|
|
|
/**
|
|
* Register a service
|
|
*/
|
|
public function bind(string $name, callable $factory): void
|
|
{
|
|
$this->services[$name] = $factory;
|
|
}
|
|
|
|
/**
|
|
* Register a singleton service
|
|
*/
|
|
public function singleton(string $name, callable $factory): void
|
|
{
|
|
$this->singletons[$name] = $factory;
|
|
}
|
|
|
|
/**
|
|
* Get a service instance
|
|
*/
|
|
public function get(string $name)
|
|
{
|
|
// Check singletons first
|
|
if (isset($this->singletons[$name])) {
|
|
if (!isset($this->services[$name])) {
|
|
$this->services[$name] = $this->singletons[$name]();
|
|
}
|
|
return $this->services[$name];
|
|
}
|
|
|
|
// Check regular services
|
|
if (isset($this->services[$name])) {
|
|
if (is_callable($this->services[$name])) {
|
|
return $this->services[$name]();
|
|
}
|
|
return $this->services[$name];
|
|
}
|
|
|
|
// Try to auto-resolve
|
|
if (class_exists($name)) {
|
|
return $this->resolve($name);
|
|
}
|
|
|
|
throw new \Exception("Service '{$name}' not found in container");
|
|
}
|
|
|
|
/**
|
|
* Auto-resolve class dependencies
|
|
*/
|
|
public function resolve(string $className)
|
|
{
|
|
$reflection = new \ReflectionClass($className);
|
|
|
|
if (!$reflection->isInstantiable()) {
|
|
throw new \Exception("Class '{$className}' is not instantiable");
|
|
}
|
|
|
|
$constructor = $reflection->getConstructor();
|
|
|
|
if (!$constructor) {
|
|
return new $className();
|
|
}
|
|
|
|
$parameters = $constructor->getParameters();
|
|
$dependencies = [];
|
|
|
|
foreach ($parameters as $parameter) {
|
|
$type = $parameter->getType();
|
|
|
|
if ($type && !$type->isBuiltin()) {
|
|
$dependencies[] = $this->resolve($type->getName());
|
|
} elseif ($parameter->isDefaultValueAvailable()) {
|
|
$dependencies[] = $parameter->getDefaultValue();
|
|
} else {
|
|
throw new \Exception("Cannot resolve parameter '{$parameter->getName()}' for class '{$className}'");
|
|
}
|
|
}
|
|
|
|
return $reflection->newInstanceArgs($dependencies);
|
|
}
|
|
|
|
/**
|
|
* Inject dependencies into an object
|
|
*/
|
|
public function inject(object $object): void
|
|
{
|
|
$reflection = new \ReflectionClass($object);
|
|
$properties = $reflection->getProperties();
|
|
|
|
foreach ($properties as $property) {
|
|
if ($property->isPublic() && !$property->isInitialized($object)) {
|
|
$type = $property->getType();
|
|
|
|
if ($type && !$type->isBuiltin()) {
|
|
$property->setValue($object, $this->get($type->getName()));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if service exists
|
|
*/
|
|
public function has(string $name): bool
|
|
{
|
|
return isset($this->services[$name]) || isset($this->singletons[$name]);
|
|
}
|
|
|
|
/**
|
|
* Get all services
|
|
*/
|
|
public function getServices(): array
|
|
{
|
|
return array_merge($this->services, $this->singletons);
|
|
}
|
|
}
|