Coder Social home page Coder Social logo

intravenous's Introduction

Trying to do some demoscene stuff in my limited spare time.

That is all.

intravenous's People

Contributors

sagacity avatar scott-coates avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

intravenous's Issues

Registering third party modules

Hi!

I really love this DI-framework, it's very similar to how I work with Java and constructor injection.

I have one issue though. When I work with third party modules (or node modules in general) such as express or fs, I would like to inject them the same way as my own modules. But I can't.
Imagine this:

var express = require('express');
module.exports = express;

This module would be loaded by Intravenous without any problems, except that the export needs to be a function. For express this works, since express is a function. But this means, when injecting express into my other modules, I would get the result of calling express(). Might work for express, but doesn't for many other modules.

Could we add support for this somehow? I was thinking something like this:

var express = require('express');
module.exports = express;
module.exports.$external = true;

... or maybe at an even higher level:

var intravenous = require('intravenous');
var express = require('express');

var container = intravenous.create();
container.external('express', express);

What do you think?

Not working on worker

If used inside a web worker (shared or dedicated), it throws the following error: ReferenceError: global is not defined
This happens because on worker there is no window object.

The workaround is to put a self.global = {} before the import, but it would be awesome to get this fixed.

Thanks

How about get by Function rather than key?

The Problem statement

If I want to retrieve an instance of MyCustomClass, I have to first register it with a key name. For that I will have to require this and all the other modules on startup. That means one file will have to require all the modules first and then initialize the application.

This seems in efficient and quite a headache to maintain that one file which contains all the required modules.

RATHER: How about requiring them in modules that actually need them instead

var Dep1 = require('./dep1');
var Dep2 = require('./dep2');

function MyCustomClass () {}
MyCustomClass.$inject = [Dep1, Dep2]; //Instead of using key name

So the main idea is to be able to query on the Class name rather than the key name. What do you think?

Please add license

Hello,

Could you add a license file, or package json with license or add license information to your README?
That would help us immensely with our automated license checking.

Best Regards

Support for request and session-scoped instances in intravenous

E.g. consider you authorize requests and have user instance which describes a current user during the request. It would be nice to have an option to store it in container and reuse in other services during a request.

The idea is taken from CDI in Java.

But it is really nice to have or at least I think it is good idea to make it possible to extend intravenous with functionality like this.

Inconsistent behavior with singleton in factory usage.

I have some strange behavior (maybe its ok, but strange) (all examples in CoffeeScript):
first - create class Foo

module.exports = class Foo

  # intravenous injection
  @$inject = ['Helper']

  constructor: (Helper, options) ->

next, register two classes - Helper and Foo

container.register 'Helper', Helper, 'singleton'
container.register 'Foo', Foo

and now use somewhere Foo factory

module.exports = class Bar

  # intravenous injection
  @$inject = ['FooFactory']

  constructor: (FooFactory, options) ->
    @_foo_instance_ = FooFactory.get()

If Helper used in Foo only - it will be re-created on every Bar call (and it may be correct - its singleton in factory context, but how about perRequest?).

Instead, if we are call use Helper in non-factory classes to - it will be created once only and re-created on Bar calls (and its looks more correctly - its singleton as registered).

May be I`m miss something, but its looks strange. And actually I cant decide what kind of behavior will be correctly. Just appoint in docs?

Use parameter names instead of $inject?

I'm curious whether you think it is a bad idea to inject based on function parameter names instead of using func.$inject.

Specifically, are there any pitfalls you can see for server side node.js code that doesn't need to be minified? Is this something you will add to the library?

Disposing of singletons

I've edited the node example to register myClass as a singleton. It does create the object only once, however it calls dispose on it the same amount of times it was created!

myDependency constructed
myClass constructed
dependency: [object Object]
nonExistentDependency: null
extraParameter: hello
Calling dispose method for service myClass
Disposing myClass!
Calling dispose method for service myClass
Disposing myClass!
Calling dispose method for service myClass
Disposing myClass!
Calling dispose method for service myDependency
Disposing myDependency!

The code used for instantiating:

var instance = container.get("myClass", "hello");
var anotherInstance = container.get("myClass", "world");
var andAnotherInstance = container.get("myClass", "intravenous");

Define Constructor Parameters When Registering?

How can I define constructor parameters when registering. Say I have a class like below.
module.exports = function ModuleContainer(
moduleName
){
'use strict';
var self = this;
this.moduleName = moduleName
/* more code */
};

When registering, how can I register two dependencies like so to pass different values to the contructor argument "moduleName". i.e.

container.register('passportModule', require('./ModuleContainer'), 'passport'); //moduleName is passed 'passport'
container.register('jwtModule', require('./ModuleContainer'), 'jasonwebtoken'); //moduleName is passed 'jasonwebtoken'

So basically I want constructor injection and to define the values of the constructor parameters when registering similar to how Unity handles this in C#

npm install has only the package.json

npm install intravenous

creates a directory with only the package.json in it. Can you fix? I've download the file but it's weird. An NPM module would be very helpful.

Thanks!

non-constructor functions

Alright, I've been trying to figure a way around this, but I it's not coming as easily as I'd hoped.

We use mongoose as an ODM on our node project. Mongoose's models cannot be used as normal javascript classes. Instead, they have functions that generate classes for you. Here's what we currently do with manual dependency passing:

# Post.coffee
makePost = (db) ->
  PostSchema = new Schema
    title: String
  PostSchema.statics.findAll = (cb) -> # go get all posts
  PostSchema.methods.titleLength = -> @title.length

  # Post is a constructor. Instances have a (new Post()).titleLength() method. Post.findAll() is a function
  Post = db.model "Post", PostSchema
  return Post
makePost.$inject = ["db"]

In short, that top-level wrapper isn't a constructor. I need to get that returned Post back out, not this.

How can we do this? Are there workarounds?

Perhaps there's a way we can detect whether it is a constructor or a normal function and support both, or simply check if the value returned from the function is an `instanceof`` the function, and if not, treat it as a normal return value instead.

Perhaps you should always respect the return value of the function? (I'm not really sure how you're getting back to this when I return something else, but maybe you're doing something fancy)

Here's a test for it that fails.

describe("containing a function registration", function() {
  beforeEach(function() {
    this.a = function() {
      return function() {
        return "a"
      }
    }
    this.container.register("a", this.a)
  })

  it("should return the original function", function() {
    a = this.container.get("a")
    expect(a()).toBe("a")
  })
})

How do I handle injection for decorator pattern scenario?

Suppose I want to register more then one binding for a Type and use different binding depending on "parameter or type" is it possible.
So for eg. I have 3 classes which Heirarchy as follows AdsRequestProcessor -inherits->TrackerRequestProcessor -inherits->RequestProcessor.
And there different classes all of which have dependency on RequestProcessor. and I want to inject AdsRequestProcessor in one and TrackerRequestProcessor in other, so a parameter or class name or any thing else while registering this dependencies will be helpful .
Some thing along the lines of NInject's contextual binding.

Singleton broken?

Hi,

singletons dont appear to work. I'm using 0.1.4-beta.

From what I can tell the instance value is cached rather than the returnValue. I replaced this line

    container.lifecycles[reg.lifecycle].set(new cacheItem(reg, instance));

with

    container.lifecycles[reg.lifecycle].set(new cacheItem(reg, returnValue || instance));

and it started working for me. You are doing the same thing at the end of the function

return returnValue || instance;

If that is true of what it returns it should be true of what it caches yes?

Best practice to combine Intravenous with revealing module pattern.

Hi Ron,
I have no issue working with intravenous in the 'regular' pass a function way.
Assuming i'm using the following to create a namespace and abstraction.
module.exports = function() {
function initialize(dependency 1, depedency2) {...}
function runInternal() { // will use the dependencies internally }
return {
run : runInternal
}
}();

what would be the best way to use intravenous? how would I register it?

-- Dan

Handle prototypal inheritance

How about creating an extends method that creates an instance of base class and then attaches it to the prototype property of the child class?

Note: Need to make sure the base class is never a singleton, else all the child classes will have the same methods.

Factories are un-ergonomic

When I think of a factory in JavaScript, I think of a function, not an object with a .get() method. This becomes particularly inconvenient when trying to pass factories around.

For example, when moving to Intravenous, my code went from

function Foo(barFactory) {
    this.doSomething = function () {
        return processSomeBars(barFactory);
    };
}

to

function Foo(barFactory) {
    this.doSomething = function () {
        return processSomeBars(barFactory.get.bind(barFactory));
    };
}

I think the solution would be to just make factories into functions. They can still have .get, .use, .dispose, and the like, but calling the factory as a function should have the same result as calling .get.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.