Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Core Interfaces Laravel Package

trinity/core-interfaces

Core contracts and interfaces for the Trinity PHP framework: shared abstractions for modules, containers, service providers, and registries. Keeps packages decoupled, testable, and interoperable across Laravel and standalone PHP projects. Lightweight, framework-agnostic, and easy to implement.

View on GitHub
Deep Wiki
Context7

Getting Started

trinity/core-interfaces is a contract-only package — it ships interfaces, not implementations. Treat it as a set of type definitions your classes satisfy, not as a library you call.

Minimal setup:

  1. composer require trinity/core-interfaces (pin the version explicitly — see Gotchas).
  2. Open vendor/trinity/core-interfaces/composer.json first: confirm the PSR-4 namespace and the php constraint, since a 2017-era release may target PHP 5.6/7.0.
  3. List the contracts before writing any code:
    php -r 'foreach (glob("vendor/trinity/core-interfaces/src/*.php") as $f) require_once $f;'
    # or simply:
    grep -rn "interface " vendor/trinity/core-interfaces/src
    
  4. Read each interface's method signatures — that is the entire documentation, because there is none.

First use case: pick the one interface that represents the concept you need (a repository, a serializer, a collection, etc.), write your own class ... implements ThatInterface, and type-hint the interface in your consumers. That's the whole day-one workflow.

Implementation Patterns

Contract-first injection. Never type-hint a concrete class you wrote; always type-hint the Trinity interface in constructors and controller actions. This keeps your code swappable and makes the interface package the only thing your domain layer depends on.

Bind in a service provider. Nothing auto-wires the contracts, so add a provider:

$this->app->bind(
    \Trinity\Core\Contracts\SomeContract::class,
    \App\Trinity\SomeContractImpl::class
);

Use singleton() for stateful implementations (caches, registries) and bind() for stateless ones.

Contextual binding for multiple implementations. If two services need different implementations of the same contract, use when()->needs()->give() rather than making the constructor smarter.

Decorator for behaviour layering. Because you own the implementations, wrapping is cheap:

class CachingRepository implements RepositoryContract
{
    public function __construct(private RepositoryContract $inner) {}
    // delegate, with caching around the hot methods
}

This is the most valuable pattern with an interface-only package — one binding change buys you caching, logging, or metrics across the whole framework.

Test doubles without mocking the library. In tests, implement the interface with a small inline fake or an anonymous class. Since the package contains no logic, there is nothing in the contract layer that needs mocking — mock your implementation's collaborators, not the interfaces.

Adapter around legacy code. If you're migrating an existing app onto Trinity, write adapters that implement the contract over your old services, register them in the container, and migrate consumers one constructor at a time.

Extension points. Interfaces are the seam for plugin registration: build a small registry keyed by contract class and let packages register implementations, then resolve through the container.

Gotchas and Tips

There are no implementations. Every method is your responsibility. If you expected helper classes, AbstractRepository, or a trait, they are not here — the package is pure interface declarations.

Released 2017, zero dependents, no maintenance. Pin an exact version in composer.json, commit composer.lock, and be prepared to vendor the package into your repo or fork it. If upstream disappears, interface-only packages are trivially forkable — copy src/ into app/Trinity/Contracts and drop the dependency if it becomes a liability.

PHP version drift is the real risk. Check for syntax your runtime rejects or, more subtly, signatures that now conflict: parameter types cannot be widened or narrowed in implementations (no contravariance before PHP 7.4), but you can add return types where the interface declares none. Run php -l and let static analysis catch signature mismatches before runtime Fatal error: Declaration must be compatible.

self vs static returns. Old interfaces often return self. In an implementation, returning static is not a safe substitute in older PHP — match the declared type exactly and verify with a quick unit test that chains the return value.

No service provider, no config, no facade. Laravel integration is entirely manual. Do not look for TrinityCoreInterfacesServiceProvider; write your own ten-line provider and register it in config/app.php (or bootstrap/providers.php on Laravel 11+).

Fat interfaces. Small framework contracts often bundle unrelated methods. Prefer defining a narrower interface of your own that extends the Trinity one, and depend on yours — this keeps test doubles small and satisfies ISP without abandoning the package's contracts where the framework requires them.

Abandoned-package checks. Run composer outdated trinity/core-interfaces and composer why trinity/core-interfaces periodically; if nothing else depends on it and the interfaces are stable, freezing the version is safer than chasing updates.

Debugging resolution failures. When you get Target [Contract] is not instantiable, the binding is missing or misspelled — dump app()->getBindings() keys and compare the fully-qualified interface name character by character. Namespace typos are the single most common failure with contract packages.

Read for annotations. Grep for @deprecated, @internal, and @todo before implementing — an @internal marker means the interface may be reworked by the framework itself, so don't couple your public API to it.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core