Browse Source

initial commit

tags/v0.1.1
Garrett Mills 3 months ago
commit
8f25acfe74
11 changed files with 205 additions and 0 deletions
  1. 8
    0
      .idea/di.iml
  2. 6
    0
      .idea/jsLibraryMappings.xml
  3. 6
    0
      .idea/misc.xml
  4. 8
    0
      .idea/modules.xml
  5. 60
    0
      .idea/workspace.xml
  6. 11
    0
      index.js
  7. 9
    0
      package.json
  8. 49
    0
      src/Container.js
  9. 29
    0
      src/DependencyInjector.js
  10. 13
    0
      src/Injectable.js
  11. 6
    0
      src/Service.js

+ 8
- 0
.idea/di.iml View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

+ 6
- 0
.idea/jsLibraryMappings.xml View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptLibraryMappings">
<includedPredefinedLibrary name="Node.js Core" />
</component>
</project>

+ 6
- 0
.idea/misc.xml View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" />
</component>
</project>

+ 8
- 0
.idea/modules.xml View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/di.iml" filepath="$PROJECT_DIR$/.idea/di.iml" />
</modules>
</component>
</project>

+ 60
- 0
.idea/workspace.xml View File

@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ChangeListManager">
<list default="true" id="212ef417-1016-4939-a831-4e9b9ec87e89" name="Default Changelist" comment="" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES">
<list>
<option value="JavaScript File" />
</list>
</option>
</component>
<component name="ProjectId" id="1V4iFKC2Omp7BW5rf02zX70z61G" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showExcludedFiles" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent">
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
<property name="WebServerToolWindowFactoryState" value="false" />
<property name="javascript.nodejs.core.library.configured.version" value="12.13.1" />
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
<property name="nodejs_package_manager_path" value="npm" />
</component>
<component name="ServiceViewManager">
<option name="viewStates">
<list>
<serviceView>
<treeState>
<expand />
<select />
</treeState>
</serviceView>
</list>
</option>
</component>
<component name="SvnConfiguration">
<configuration />
</component>
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="212ef417-1016-4939-a831-4e9b9ec87e89" name="Default Changelist" comment="" />
<created>1576518662544</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1576518662544</updated>
<workItem from="1576518666753" duration="230000" />
<workItem from="1576762358601" duration="4552000" />
</task>
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="1" />
</component>
</project>

+ 11
- 0
index.js View File

@@ -0,0 +1,11 @@
const DependencyInjector = require('./src/DependencyInjector')
const Injectable = require('./src/Injectable')
const Container = require('./src/Container')
const Service = require('./src/Service')

module.exports = exports = {
DependencyInjector,
Injectable,
Container,
Service
}

+ 9
- 0
package.json View File

@@ -0,0 +1,9 @@
{
"name": "flitter-di",
"version": "0.1.0",
"description": "An elegant, robust dependency-injector for Node.js",
"main": "index.js",
"repository": "https://git.garrettmills.dev/flitter/di",
"author": "Garrett Mills",
"license": "MIT"
}

+ 49
- 0
src/Container.js View File

@@ -0,0 +1,49 @@
class Container {
constructor(definitions = {}) {
this.definitions = definitions
this.instances = {}
this.statics = {}
this.di = false
}

service(service = false) {
if ( service === false ) {
return new Proxy({}, {
get: (obj, prop) => {
return this.service(prop)
}
})
}

if ( !this.definitions[service] ) {
throw new Error('No such service registered with this container.')
}

// Store the static reference first.
// This allows us to resolve circular dependencies.
if ( !this.statics[service] ) {
this.statics[service] = this.definitions[service]
this.di.make(this.statics[service])
}

if ( !this.instances[service] ) {
const ServiceClass = this.statics[service]
this.instances[service] = new ServiceClass()
}

return this.instances[service]
}

register(service_name, service_class) {
this.definitions[service_name] = service_class
}

__is_injectable(Class) {
return (
Class.services
&& Array.isArray(Class.services)
)
}
}

module.exports = exports = Container

+ 29
- 0
src/DependencyInjector.js View File

@@ -0,0 +1,29 @@
const Container = require('./Container')
class DependencyInjector {
constructor(container = new Container()) {
this.container = container
this.container.di = this
}

make(Class) {
if ( !this.__is_injectable(Class) ) {
throw new Error('Cannot inject non-injectable class.')
}

Class.__inject(this.container)
return Class
}

service(name) {
return this.container.service(name)
}

__is_injectable(Class) {
return (
typeof Class.__inject === 'function'
&& Class.__inject.length > 0
)
}
}

module.exports = exports = DependencyInjector

+ 13
- 0
src/Injectable.js View File

@@ -0,0 +1,13 @@
class Injectable {
static get services() {
return []
}

static __inject(container) {
this.services.forEach(name => {
this.prototype[name] = container.service(name)
})
}
}

module.exports = exports = Injectable

+ 6
- 0
src/Service.js View File

@@ -0,0 +1,6 @@
const Injectable = require('./Injectable')
class Service extends Injectable {

}

module.exports = exports = Service

Loading…
Cancel
Save