Inversifyjs: Add Container method to create instances of unbounded classes

Created on 13 Mar 2017  路  5Comments  路  Source: inversify/InversifyJS

Feature request to add a Container method capable of create instances of unbounded classes.

Example

import { Container, injectable } from "inversify";
import "reflect-metadata";

@injectable()
class Katana {
    public hit() {
        return "cut!";
    }
}

@injectable()
class Ninja implements Ninja {
    public constructor(private katana: Katana) {
    }

    public fight() { return this.katana.hit(); }
}

const container = new Container();
container.bind(Katana).toSelf();
container.create(Ninja);  // Creates a Ninja instance
container.get(Ninja);     // throws: No matching bindings found for serviceIdentifier: Ninja

In this example, create would behave like get except for:

  • it only works on classes, not symbols or string identifiers.
  • it doesn't look for the class binding, it just creates an instance injecting its dependencies.

Use cases

Every time you need to create an instance of an _injectable class_, but you don't need/want to bind it in the Container. It may apply to the application root.

In my particular use case, I want to load plugins at runtime, these plugins are injectable classes that I want to create and register in a plugin manager, therefore, I don't need to bind them in the Container.

Other injectors:

According to documentation Unity's Resolve method seems to behave like that.

public ManagementController(ITenantStore tenantStore)
{
  this.tenantStore = tenantStore;
}

var container = new UnityContainer();
container.RegisterType<ITenantStore, TenantStore>();

var controller = container.Resolve<ManagementController>();

Environment

Version: 3.1.0

Most helpful comment

Amazing. Thanks a lot.

All 5 comments

Thanks for your feedback :+1: I will review this during the weekend :)

I have started to work on this I only have one question so far. If you look at the unity example, they resolve ManagementController and that has a dependency on ITenantStore. There are no bindings for ManagementController but there is a binding for ITenantStore this makes sense because it would be very complicated (if not impossible) to resolve all the sub-dependencies without bindings.

I can implement container.resolve but I'm afraid it will only be able to resolve the root dependency. I don't know if this works in your plugin scenario? For plugin scenarios one option could be using multiple container modules or multiple child containers.

Hi @remojansen, that's great news.

It didn't occur to me before, I was thinking only in the root class. I guess the plugin should be able to register bindings somehow, probably via an injected service or exporting a declaration.

In a previous C# project, we used a custom DI container that would auto-bind any unbound dependency along the way. A global config option would say if it should auto-bind as singleton (we used it as singleton). But something like that may be pushing it too far for a generic container.

Bottom line, I think the root class scenario is enough and doesn't force you to make arguable choices.

This has now been implemented by PR #512 and is available in the [email protected] release (should be available over the next hour or so...). Thanks a lot for sharing your feedback with us 馃憤

Amazing. Thanks a lot.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

AriaFallah picture AriaFallah  路  4Comments

remojansen picture remojansen  路  4Comments

stjepangolemac picture stjepangolemac  路  5Comments

remojansen picture remojansen  路  3Comments

AlexanderKiriluyk picture AlexanderKiriluyk  路  4Comments