All Projects → vue-ioc → vue-ioc

vue-ioc / vue-ioc

Licence: other
IoC and DI for Vue powered by InversifyJS and inspired by Angular Module syntactic sugar.

Programming Languages

typescript
32286 projects
Vue
7211 projects
javascript
184084 projects - #8 most used programming language
HTML
75241 projects

Projects that are alternatives of or similar to vue-ioc

Inversifyjs
InversifyJS is a lightweight inversion of control (IoC) container for TypeScript and JavaScript apps. An IoC container uses a class constructor to identify and inject its dependencies. InversifyJS has a friendly API and encourages the usage of the best OOP and IoC practices.
Stars: ✭ 8,399 (+21435.9%)
Mutual labels:  ioc, dependency-injection, inversifyjs
Qframework
Unity3D System Design Architecture
Stars: ✭ 2,326 (+5864.1%)
Mutual labels:  ioc, dependency-injection, inversion-of-control
Singularity
A extremely fast ioc container for high performance applications
Stars: ✭ 63 (+61.54%)
Mutual labels:  ioc, dependency-injection, inversion-of-control
Kangaru
🦘 A dependency injection container for C++11, C++14 and later
Stars: ✭ 297 (+661.54%)
Mutual labels:  ioc, dependency-injection, inversion-of-control
stashbox
A lightweight, fast, and portable dependency injection framework for .NET-based solutions.
Stars: ✭ 120 (+207.69%)
Mutual labels:  ioc, dependency-injection, inversion-of-control
Ditranquillity
Dependency injection for iOS (Swift)
Stars: ✭ 317 (+712.82%)
Mutual labels:  ioc, dependency-injection, inversion-of-control
React Ioc
Hierarchical Dependency Injection with new React 16 Context API
Stars: ✭ 133 (+241.03%)
Mutual labels:  ioc, dependency-injection, inversion-of-control
telephone-ts
Telephone-ts: The "Event Emitter-less" TypeScript Event Architecture.
Stars: ✭ 22 (-43.59%)
Mutual labels:  dependency-injection, inversion-of-control, inversifyjs
Typhoon
Powerful dependency injection for Objective-C ✨✨ (https://PILGRIM.PH is the pure Swift successor to Typhoon!!)✨✨
Stars: ✭ 2,711 (+6851.28%)
Mutual labels:  ioc, dependency-injection, inversion-of-control
Typedi
Simple yet powerful dependency injection tool for JavaScript and TypeScript.
Stars: ✭ 2,832 (+7161.54%)
Mutual labels:  ioc, dependency-injection, inversion-of-control
granitic
Web/micro-services and IoC framework for Golang developers
Stars: ✭ 32 (-17.95%)
Mutual labels:  ioc, dependency-injection, inversion-of-control
iocgo
A lightweight Inversion of Control (IoC) (Dependency Injection) container for Golang
Stars: ✭ 36 (-7.69%)
Mutual labels:  ioc, dependency-injection, inversion-of-control
diod
A very opinionated inversion of control (IoC) container and dependency injector for Typescript, Node.js or browser apps.
Stars: ✭ 36 (-7.69%)
Mutual labels:  ioc, dependency-injection, inversion-of-control
Go Spring
基于 IoC 的 Go 后端一站式开发框架 🚀
Stars: ✭ 744 (+1807.69%)
Mutual labels:  ioc, dependency-injection, inversion-of-control
ThunderboltIoc
One of the very first IoC frameworks for .Net that has no reflection. An IoC that casts its services before thunder casts its bolts.
Stars: ✭ 40 (+2.56%)
Mutual labels:  ioc, dependency-injection, inversion-of-control
Container Ioc
Inversion of Control container & Dependency Injection for Javascript and Node.js apps powered by Typescript.
Stars: ✭ 89 (+128.21%)
Mutual labels:  ioc, dependency-injection, inversion-of-control
nodejs-boilerplate
Clean Architecture for node.js projects (Typescript + Express + TypeORM + Typedi)
Stars: ✭ 199 (+410.26%)
Mutual labels:  dependency-injection, inversion-of-control, inversifyjs
Ioc
🦄 lightweight (<1kb) inversion of control javascript library for dependency injection written in typescript
Stars: ✭ 171 (+338.46%)
Mutual labels:  ioc, dependency-injection, inversion-of-control
waiter
Dependency injection, Inversion of control container for rust with compile time binding.
Stars: ✭ 71 (+82.05%)
Mutual labels:  ioc, dependency-injection, inversion-of-control
vesselize
⛵ A JavaScript IoC container that works seamlessly with Vue.js and React.
Stars: ✭ 22 (-43.59%)
Mutual labels:  ioc, dependency-injection, inversion-of-control

vue-ioc

IoC and DI for Vue powered by InversifyJS and inspired by Angular @Module syntactic sugar.

Required Opinionated Stack

Features

  1. Hierarchical IoC Container defined in @Module by providers (using InversifyJS under the hood). The hierarchy is bound to Vue components tree.
  2. Autostart - instantiating top level services when container has been started (for background tasks similar to @Effects from ngrx).
  3. @InjectReactive() - makes injected dependency 'deeply reactive' in Vue template.
  4. Instance Handlers - @PostConstruct and @BeforeDestroy - decorators for methods called when instance is created or destroyed by container.
  5. Custom Instance Handlers ie. @OnEvent('submitForm')
  6. providedIn 'root' or 'self' - select where will be bound @Injectable (friendly for tree shakeable singletons and lazy loaded @Modules)

Planned features (not ready yet)

  1. State Injectors for Vuex and MobX.
  2. vue-cli integration

Caveats / Limitations

  • @Module can be bound only to Vue component.
  • You can't use @Inject() for Vue component constructor arguments (because you can't define own constructor using vue-class-component). Only Vue component class fields are supported.

Installation

vue-ioc uses following peerDependencies:

  • inversify
  • reflect-metadata
  • vue-class-component
  • vue
# NPM
npm install @vue-ioc/core inversify reflect-metadata vue-class-component vue --save

# Yarn
yarn add @vue-ioc/core inversify reflect-metadata vue-class-component vue

You must explicitly install vue-ioc via Vue.use() in your app main entrypoint:

// main.ts
import Vue from 'vue'
import {VueIocPlugin} from '@vue-ioc/core' 

Vue.use(VueIocPlugin)

Quick Start

Edit vue-ioc basic example

Create simple injectable service HttpService:

// ./services/HttpService.ts
import {Injectable} from '@vue-ioc/core';

@Injectable()
export class HttpService {
    public get(url: string): Promise<any> {
        return fetch(url).then(rs => rs.json());
    }
}

Add root container using @Module decorator at your top level App component and setup providers:

// App.vue
<template>
    <div>
        <HelloWorld/>
    </div>
</template>
<script lang="ts">
    import Vue from 'vue'
    import Component from 'vue-class-component'
    import {Module} from '@vue-ioc/core';
    import {HttpService} from './services/HttpService';
    import HelloWorld from './components/HelloWorld.vue';
    
    @Module({
        providers: [
            HttpService
        ]
    })
    @Component({
      components: { HelloWorld }
    })
    export default class App extends Vue {
    }
</script>

Inject HttpService to <HelloWorld> component:

// ./components/HelloWorld.vue
<template>
    <div>
        <h2 v-if="user">Hello {{user.firstName}} {{user.lastName}}!</h2>
    </div>
</template>
<script lang="ts">
    import Vue from 'vue'
    import Component from 'vue-class-component'
    import {Inject} from '@vue-ioc/core';
    import {HttpService} from '../services/HttpService';

    @Component()
    export default class HelloWorld extends Vue {

        @Inject()
        public httpService: HttpService;
        
        public user = null;

        public async created() {
            this.user =  await this.httpService.get('./hello.json');
        }
    }
</script>

Providers

@Module({
    providers: [
        // useClass
        { provide: HttpService, useClass: HttpService },
        
        // useClass shortcut 
        HttpService,
        
        // useValue
        { provide: HttpService, useValue: httpService },
        
        // useFactory
        { provide: HttpService, useFactory: (injector) => /* ...injector.get(FooService)... */ }
    ] 
})

providedIn

Default value: 'self' Available values: 'root', 'self'

@Injectable( { providedIn: 'root' } ) will bind service in root (App) container always as singleton.

You may also override this setting at @Module providers level in both directions:

@Module({
    providers: [
        { provide: HttpService, useClass: HttpService, providedIn: 'root' },   // overrides @Injectable()
        { provide: OtherService, useClass: OtherService, providedIn: 'self' }, // overrides @Injectable( {providedIn: 'root'} )
    ] 
})

Custom Instance Handlers

@PostConstruct() and @BeforeDestroy() are two built in instance listeners. You may create custom instance handlers like @OnEvent('submitForm') by creating a decorator using createInstanceHandlerDecorator

  1. Prepare the most basic EventBus implementation:
// bus/EventBus.ts
import Vue from 'vue';
import {Injectable} from '@vue-ioc/core';

@Injectable()
export class EventBus {

    private bus: Vue = new Vue();

    dispatch(name: string, data: any) {
        this.bus.$emit(name, data);
    }

    addListener(name: string, listener: (data: any) => void) {
        this.bus.$on(name, listener)
    }

    removeListener(name: string, listener: (data: any) => void) {
        this.bus.$off(name, listener)
    }
}
  1. Create @OnEvent(name:string) decorator
// bus/OnEvent.ts
import {createInstanceHandlerDecorator} from '@vue-ioc/core';
import {EventBus} from './EventBus';

export function OnEvent(name: string) {
    return createInstanceHandlerDecorator(({injector, instance, method}) => {
        // attach handler - a place where listeners should be attached
        const bus: EventBus = injector.get(EventBus); // you have access to injector where all services can be retrieved
        const boundMethod = instance[method].bind(instance); // bound method to `this` of instance
        bus.addListener(name, boundMethod);
        return () => { 
            // detach handler - a place where all listeners should be detached
            bus.removeListener(name, boundMethod);
        };
    });
}
  1. Dispatch event from view:
// view/Form.vue
<template>
    <div>
        <button @click="submitForm">Submit</button>
    </div>
</template>
<script lang="ts">
    import Vue from 'vue'
    import Component from 'vue-class-component'
    import {Inject} from '@vue-ioc/core';
    import {EventBus} from '../bus/EventBus';

    @Component()
    export default class SomeForm extends Vue {

        @Inject()
        public bus!: EventBus;

        public submitForm() {
            this.bus.dispatch('submitForm', { firstName: 'John', lastName: 'Doe'})
        }
    }
</script>
  1. Handle event in external action:
// actions/SubmitForm.ts
import {OnEvent} from '../bus/OnEvent'
import {Injectable} from '@vue-ioc/core';

@Injectable()
export class SubmitForm {
  
  @OnEvent('submitForm')
  perform (data) {
     // do something with data
  }
}

Inversify Container Options

vue-ioc uses following default options for creating Inversify containers:

{
    autoBindInjectable: false,
    defaultScope: 'Singleton',
    skipBaseClassChecks: true,
}

To override or add other options, please use containerOptions of plugin options:

Vue.use(VueIocPlugin, {
  containerOptions: {
    // options of Inversify container:
    // https://github.com/inversify/InversifyJS/blob/master/wiki/container_api.md#container-options
  }
})
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].