dev-resources.site
for different kinds of informations.
Safely restructure your codebase with Dependency Graphs
Published at
7/29/2024
Categories
typescript
dependency
graph
binding
Author
t_bi_a6d385ba2e05d3d128
Author
23 person written this
t_bi_a6d385ba2e05d3d128
open
Using "inversify" is a key to create Deoencency-Graph-Binding
import { Container } from "inversify";
var container = new Container();
export { container };
import { interfaces, namedConstraint, taggedConstraint, traverseAncerstors, typeConstraint } from "inversify";
class BindingHelper
{
targetNamed(request: interfaces.Request, name: string | number | symbol): boolean
{
return request != null && request.target.matchesNamedTag(name.toString());
}
targetTagged(request: interfaces.Request, key: string | number | symbol, value: unknown): boolean
{
return request != null && request.target.matchesTag(key)(value);
}
targetIsDefault(request: interfaces.Request): boolean
{
return request != null && request.target != null && !request.target.isNamed() && !request.target.isTagged();
}
injectInto(request: interfaces.Request, parent: (NewableFunction | string)): boolean
{
return request != null && typeConstraint(parent)(request.parentRequest);
}
parentNamed(request: interfaces.Request, name: string | number | symbol): boolean
{
return request != null && namedConstraint(parent)(request.parentRequest);
}
parentTagged(request: interfaces.Request, tag: string | number | symbol, value: unknown): boolean
{
return request != null && taggedConstraint(tag)(value)(request.parentRequest);
}
anyAncestorIs(request: interfaces.Request, ancestor: (NewableFunction | string)): boolean
{
return traverseAncerstors(request, typeConstraint(ancestor));
}
noAncestorIs(request: interfaces.Request, ancestor: (NewableFunction | string)): boolean
{
return !traverseAncerstors(request, typeConstraint(ancestor));
}
anyAncestorTagged(request: interfaces.Request, tag: string | number | symbol, value: unknown): boolean
{
return traverseAncerstors(request, taggedConstraint(tag)(value));
}
noAncestorTagged(request: interfaces.Request, tag: string | number | symbol, value: unknown): boolean
{
return !traverseAncerstors(request, taggedConstraint(tag)(value));
}
anyAncestorNamed(request: interfaces.Request, name: string | number | symbol): boolean
{
return traverseAncerstors(request, namedConstraint(name));
}
noAncestorNamed(request: interfaces.Request, name: string | number | symbol): boolean
{
return !traverseAncerstors(request, namedConstraint(name));
}
}
var when = new BindingHelper();
export { when };
import { Container, interfaces } from "inversify";
import { when } from "./context-binding-helper";
interface DependencyBranch
{
from(type: any): DependencyGraphHelper;
}
class DependencyGraphHelper implements DependencyBranch
{
private container: Container;
private graphs: any[] = [];
private isBranching: boolean;
private branchNode: any;
bind(identifier: any, type: any, isConstant: boolean = false): DependencyGraphHelper
{
if (this.isBranching)
{
console.error('Please specify which class to be branched from. Parameters: ', identifier, ' ', type);
}
var parent = this.graphs[this.graphs.length - 1];
var node = { identifier: identifier, type: type, parent: parent, isConstant: isConstant };
this.graphs.push(node);
return this;
}
branch(identifier: any, type: any, isConstant: boolean = false): DependencyBranch
{
if (this.graphs.length == 0)
{
console.error('Dependency graph cannot start with a "branch". It must start with a "bind" function.Parameters: ', identifier, ' ', type);
}
if (this.isBranching)
{
console.error('Please specify which class to be branched from. Parameters: ', identifier, ' ', type);
}
this.isBranching = true;
this.branchNode = { identifier: identifier, type: type, isConstant: isConstant };
return this;
}
from(type: any): DependencyGraphHelper
{
if (this.isBranching == false)
{
console.error('A "from" function must be called after a "branch" function. Parameters: ', type);
}
this.isBranching = false;
var parent = this.graphs.filter(i => i.type == type).pop();
this.branchNode.parent = parent;
this.graphs.push(this.branchNode);
return this;
}
registerTo(container: Container): void
{
if (this.isBranching)
{
console.error('Please specify which class to be branched from before call "register" function.');
}
this.container = container;
for (let index = 0; index < this.graphs.length; index++)
{
const graph = this.graphs[index];
this.registerGraph(graph);
}
this.graphs = [];
this.container = null;
}
private registerGraph(graph: any): void
{
if (graph.isConstant)
{
this.bindToConstant(graph);
}
else
{
this.bindTo(graph);
}
}
private bindTo(graph: any): void
{
this.container.bind(graph.identifier).to(graph.type).when(request =>
{
return this.recursiveCheckBindingCondition(request, graph);
});
}
private bindToConstant(graph: any): void
{
this.container.bind(graph.identifier).toConstantValue(graph.type).when(request =>
{
return this.recursiveCheckBindingCondition(request, graph);
});
}
private recursiveCheckBindingCondition(request: interfaces.Request, graph: any): boolean
{
if (graph.parent == null)
{
return true;
}
var injected = when.injectInto(request, graph.parent.type) && this.recursiveCheckBindingCondition(request.parentRequest, graph.parent);
return injected;
}
}
var dependencyGraph = new DependencyGraphHelper();
export { dependencyGraph };
import { dependencyGraph } from "../../common/ioc-helper/dependency-graph-helper";
import { container } from "../../ioc/ioc-container";
import { MonkeyClimb } from "../monkey/monkey-climb";
import { MonkeyControl } from "../monkey/monkey-control";
import { MonkeyEat } from "../monkey/monkey-eat";
import { MonkeyFindFood } from "../monkey/monkey-find-food";
import { MonkeySwingThroughTheTree } from "../monkey/monkey-swing-through-the-tree";
import { MONKEY } from "./animal-ioc-config";
export default class DependenceGraphBinding
{
public register(): void
{
this.registerMonkey();
}
private registerMonkey(): void
{
dependencyGraph
.bind(MONKEY.CONTROL,MonkeyControl)
.branch(MONKEY.EAT,MonkeyEat).from(MonkeyControl)
.branch(MONKEY.FIND_FOOD,MonkeyFindFood).from(MonkeyControl)
.branch(MONKEY.FIND_FOOD,MonkeyClimb).from(MonkeyFindFood)
.branch(MONKEY.FIND_FOOD,MonkeySwingThroughTheTree).from(MonkeyFindFood)
.registerTo(container);
}
}
dependency Article's
30 articles in total
Ore: Advanced Dependency Injection Package for Go
read article
vcpkg - how to modify dependencies
read article
CocoaPods is in Maintenance Mode
read article
Safely restructure your codebase with Dependency Graphs
currently reading
Understanding Dependencies in Programming
read article
A zoom installer script for linux
read article
Loose Coupling and Dependency Injection (DI) principle
read article
Dependency Injection in swift
read article
Dependency relation in AWS CDK
read article
CORS how to enable them in .NET?
read article
Angular Dependency Injection
read article
Dependency management made easy with Dependabot and GitHub Actions
read article
Jetpack compose โ Dependency injection with Dagger/HILT
read article
Dependencies in node project
read article
Fixing vulnerabilities found in a dependency tree
read article
How to create your own dependency injection framework in Java
read article
Reduzindo a quantidade de Branchs na criaรงรฃo de Objetos com uma estrutura plugรกvel
read article
NodeJs - Dependency injection, make it easy
read article
A Step by Step Guide to ASP.NET Core Dependency Injection
read article
The Basics of Dependency Maintenance in NPM/yarn
read article
The troubles of modern software dependency management and what to do about them
read article
Loose Coupling Basics
read article
Correctly defining CDK dependencies in L3 constructs
read article
What dependency hell looks like, and how to avoid it
read article
How to create your own dependency injection framework in Java
read article
Dependency Inversion Principle in Swift
read article
Angular: Create a custom dependency injection
read article
Dagger with a Hilt
read article
How to find what is the dependency of a function, class, or variable in ES6 via AST
read article
Data Dependency Graph
read article
Featured ones: