Skip to content

Commit f85c539

Browse files
authored
Merge pull request #299 from koriym/feature/psalm-domain-types
Enhance type safety with Psalm domain types and fix static analysis errors
2 parents 33a4a68 + d016ec3 commit f85c539

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+363
-139
lines changed

.github/workflows/demo-php8.yml renamed to .github/workflows/demo.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
runs-on: ubuntu-latest
1212
steps:
1313
- name: Checkout
14-
uses: actions/checkout@v2
14+
uses: actions/checkout@v4
1515

1616
- name: Setup PHP
1717
uses: shivammathur/setup-php@v2
@@ -22,10 +22,10 @@ jobs:
2222

2323
- name: Get composer cache directory
2424
id: composer-cache
25-
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
25+
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
2626

2727
- name: Cache dependencies
28-
uses: actions/cache@v2
28+
uses: actions/cache@v4
2929
with:
3030
path: ${{ steps.composer-cache.outputs.dir }}
3131
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
@@ -35,4 +35,4 @@ jobs:
3535
run: composer install --no-interaction --no-progress --prefer-dist
3636

3737
- name: Run Demo
38-
run: php demo-php8/run.php
38+
run: php demo/run.php

.github/workflows/update-copyright-years-in-license-file.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ jobs:
99
run:
1010
runs-on: ubuntu-latest
1111
steps:
12-
- uses: actions/checkout@v2
12+
- uses: actions/checkout@v4
1313
with:
1414
fetch-depth: 0
1515
- uses: FantasticFiasco/action-update-license-year@v2

CLAUDE.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
Ray.Di is a dependency injection and AOP (Aspect-Oriented Programming) framework for PHP inspired by Google Guice. It provides annotations-based dependency injection with support for AOP interceptors.
8+
9+
## Core Architecture
10+
11+
### Key Components
12+
- **AbstractModule**: Base class for defining dependency bindings. Modules are composed using `install()` and can be overridden using `override()`
13+
- **Injector**: Main entry point that manages the DI container and creates instances. Auto-registers generated proxy classes and handles untargeted bindings
14+
- **Bind**: Fluent API for creating bindings (`.to()`, `.toProvider()`, `.toInstance()`, `.in()`)
15+
- **Container**: Internal storage for all bindings and dependencies
16+
- **Annotations**: Located in `src/di/Di/` - includes `@Inject`, `@Named`, `@Assisted`, etc.
17+
18+
### Directory Structure
19+
- `src/di/`: Core DI framework code
20+
- `src-deprecated/`: Legacy code maintained for compatibility
21+
- `tests/di/`: Unit tests with extensive fake classes for testing
22+
- `demo/` and `demo-php8/`: Examples showing framework usage
23+
- Compiled proxy classes are cached in configurable temp directories
24+
25+
## Development Commands
26+
27+
### Testing
28+
```bash
29+
composer test # Run PHPUnit tests
30+
composer coverage # Generate test coverage with Xdebug
31+
composer pcov # Generate coverage with PCOV (faster)
32+
```
33+
34+
### Code Quality
35+
```bash
36+
composer cs # Run PHP_CodeSniffer
37+
composer cs-fix # Auto-fix coding standards
38+
composer sa # Static analysis (Psalm + PHPStan)
39+
composer clean # Clear analysis caches
40+
```
41+
42+
### Build Pipeline
43+
```bash
44+
composer build # Full build: cs + sa + pcov + metrics
45+
composer tests # Quick check: cs + sa + test
46+
```
47+
48+
### Analysis Tools
49+
```bash
50+
composer phpmd # PHP Mess Detector
51+
composer metrics # Generate code metrics
52+
composer baseline # Update static analysis baselines
53+
```
54+
55+
## Testing Strategy
56+
57+
- Tests use extensive fake classes in `tests/di/Fake/` to simulate real-world scenarios
58+
- Supports both PHP 7.2+ and PHP 8+ with separate test suites
59+
- Cache files are automatically cleaned between test runs
60+
- AOP proxy generation is tested with temporary directories
61+
62+
## Framework Patterns
63+
64+
### Module Definition
65+
```php
66+
class MyModule extends AbstractModule
67+
{
68+
protected function configure(): void
69+
{
70+
$this->bind(Interface::class)->to(Implementation::class);
71+
$this->bind(Service::class)->toProvider(ServiceProvider::class);
72+
}
73+
}
74+
```
75+
76+
### Injection Usage
77+
```php
78+
$injector = new Injector(new MyModule());
79+
$instance = $injector->getInstance(Interface::class);
80+
```
81+
82+
## Important Notes
83+
84+
- Ray.Di generates proxy classes for AOP which are cached in temp directories
85+
- The framework supports both constructor and setter injection
86+
- All bindings are resolved at runtime with automatic proxy weaving for aspects
87+
- Multi-binding support allows collecting multiple implementations of the same interface

demo/01a-linked-binding.php

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,9 @@ interface MovieListerInterface
2121

2222
class MovieLister implements MovieListerInterface
2323
{
24-
public $finder;
25-
26-
public function __construct(FinderInterface $finder)
27-
{
28-
$this->finder = $finder;
29-
}
24+
public function __construct(
25+
public FinderInterface $finder
26+
){}
3027
}
3128

3229
class FinderModule extends AbstractModule

demo/01b-linked-binding-setter-injection.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,9 @@ interface MovieListerInterface
2222

2323
class MovieLister implements MovieListerInterface
2424
{
25-
public $finder;
25+
public FinderInterface $finder;
2626

27-
/**
28-
* @Inject
29-
*/
27+
#[Inject]
3028
public function setFinder(FinderInterface $finder)
3129
{
3230
$this->finder = $finder;

demo/02-provider-binding.php

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,9 @@ interface MovieListerInterface
3939

4040
class MovieLister implements MovieListerInterface
4141
{
42-
/** @var Finder */
43-
public $finder;
44-
45-
public function __construct(FinderInterface $finder)
46-
{
47-
$this->finder = $finder;
42+
public function __construct(
43+
public FinderInterface $finder
44+
){
4845
}
4946
}
5047

demo/02a-named-by-qualifier.php

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,32 +16,21 @@ class LegacyFinder implements FinderInterface
1616
{
1717
}
1818

19-
class ModernFinder implements FinderInterface
20-
{
21-
}
22-
2319
interface MovieListerInterface
2420
{
2521
}
2622

2723
class MovieLister implements MovieListerInterface
2824
{
29-
public $finder;
25+
public FinderInterface $finder;
3026

31-
/**
32-
* @Legacy
33-
*/
34-
public function __construct(FinderInterface $finder)
27+
public function __construct(#[Legacy] FinderInterface $finder)
3528
{
3629
$this->finder = $finder;
3730
}
3831
}
3932

40-
/**
41-
* @Annotation
42-
* @Target("METHOD")
43-
* @Qualifier
44-
*/
33+
#[Attribute(Attribute::TARGET_PARAMETER), Qualifier]
4534
class Legacy
4635
{
4736
}

demo/02b-named-by-named.php

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,9 @@ interface MovieListerInterface
2626

2727
class MovieLister implements MovieListerInterface
2828
{
29-
public $finder;
30-
31-
/**
32-
* @Named("legacy")
33-
*/
34-
public function __construct(FinderInterface $finder)
35-
{
36-
$this->finder = $finder;
37-
}
29+
public function __construct(
30+
#[Named('legacy')] public FinderInterface $finder
31+
){}
3832
}
3933

4034
class FinderModule extends AbstractModule

demo/03-injection-point.php

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,22 @@ interface MovieListerInterface
1919

2020
class Finder implements FinderInterface
2121
{
22-
private $className;
22+
private string $className;
2323

24-
public function __construct($className)
24+
public function __construct(string $className)
2525
{
2626
$this->className = $className;
2727
}
2828

29-
public function find()
29+
public function find(): string
3030
{
3131
return sprintf('search for [%s]', $this->className);
3232
}
3333
}
3434

3535
class MovieLister implements MovieListerInterface
3636
{
37-
/** @var Finder */
38-
public $finder;
37+
public FinderInterface $finder;
3938

4039
public function __construct(FinderInterface $finder)
4140
{
@@ -45,12 +44,10 @@ public function __construct(FinderInterface $finder)
4544

4645
class FinderProvider implements ProviderInterface
4746
{
48-
private $ip;
49-
50-
public function __construct(InjectionPointInterface $ip)
51-
{
52-
$this->ip = $ip;
53-
}
47+
public function __construct(
48+
public InjectionPointInterface $ip
49+
)
50+
{}
5451

5552
/**
5653
* {@inheritdoc}

demo/05b-constructor-binding-setter-injection.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class Finder implements FinderInterface
2727

2828
class MovieLister implements MovieListerInterface
2929
{
30-
public $finder;
30+
public FinderInterface $finder;
3131

3232
/**
3333
* Setter Injection with no Inject annotation

0 commit comments

Comments
 (0)