Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Container method to create instances of unbounded classes #505

Closed
pmoleri opened this issue Mar 13, 2017 · 5 comments
Closed

Add Container method to create instances of unbounded classes #505

pmoleri opened this issue Mar 13, 2017 · 5 comments

Comments

@pmoleri
Copy link

pmoleri commented Mar 13, 2017

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

@remojansen
Copy link
Member

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

@remojansen
Copy link
Member

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.

@pmoleri
Copy link
Author

pmoleri commented Mar 22, 2017

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.

remojansen added a commit that referenced this issue Mar 22, 2017
@remojansen remojansen mentioned this issue Mar 22, 2017
9 tasks
remojansen added a commit that referenced this issue Mar 22, 2017
@remojansen
Copy link
Member

This has now been implemented by PR #512 and is available in the inversify@3.3.0 release (should be available over the next hour or so...). Thanks a lot for sharing your feedback with us 👍

remojansen added a commit that referenced this issue Mar 22, 2017
* Implemments #505

* Added docs for #505
remojansen added a commit that referenced this issue Mar 22, 2017
* Implemments #505

* Added docs for #505

* Implements #497
@pmoleri
Copy link
Author

pmoleri commented Mar 23, 2017

Amazing. Thanks a lot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants