Closed shlomiassaf closed 7 years ago
The type information is only emitted when a decorator is applied :cry: Have you take a look to inversify-binding-decorators?
The type information is only emitted when a decorator is applied :cry:
Have you tried inversify-binding-decorators?
Bummer :/
Yes I know inversify-binding-decorators, used it before but its a 70% solution... anyway no types no good :)
BTW, can you publish nversify-binding-decorators for 3.0.1? I saw it was commited but it's not on npm
Interesting thing... how are you going to manage bindings where multiple containers are an option?
Sure! I will try my best to publish this evening but I just arrived from a week awake and I have to write back to many emails before :sob:
About your question about multiple containers...
Lets say that you have two npm modules:
@provide
annotation. The annotation is used in a class Ninja@provide
annotation. The annotation is used in a class KatanaBoth modules are then consumed from a third module C. But how can we get the Katana to be injected into the Ninja if the bindings and metadata are in two different containers. There are two available solutions:
@remojansen no worries, publish when you can :)
Thanks for the help! I will close this now.
Hi, I'm looking for something like what was mentioned here:
const myClass = container.instantiate(MyClass);
Given that the class is decorated, it would be nice to have a way to construct an instance of without binding it to the container. Is there any way to do it?
@pmoleri the container is how inversify works.
If you want to get around doing the container.bind
If you want to get around creating an instance whenever you need one, consider setting up a factory and injecting that into the function you want to generate other objects from.
Or you could (although I think it goes against the whole idea of DI) and export a function from your inversify.config.ts like so:
const GetMyClassFactory = (identifier: string): MyClass => {
return container.get<IClass>('MyClass');
}
export { GetMyClassFactory }
Hi @Dirrk,
Thanks for your input. I get that inversify-binding-decorators
gives me a shortcut to auto bind implementations, but that's actually what I'm trying to avoid.
In this case, I want to use the container to construct an instance of B
, but I don't want to get it registered in the container.
E.g.:
@injectable()
class A {
prop = "test";
}
@injectable()
class B {
constructor(private a: A) {
}
}
const container = new Container();
container.bind(A).to(A);
container.get(B); // Error: No matching bindings found for serviceIdentifier: B
At this point, the container has all the information it needs to construct an instance of B
.
I agree get
should fail because it the binding wasn't registered.
But another function such as container.create(class)
could be implemented to enable users to create a class without register the binding.
As a workaround I could just bind/get/unbind, but I guess the create
option may be a nice addition to the api.
I can create a new issue if you it’s worth it.
@pmoleri, thanks for bringing more light into the issue as I now have a much better understanding of what you want to do. However, I would like to know a use case for this before we pull anyone in.
For instance, using your example with A and B. Why would you not just bind B? And more importantly why do you need to unbind it to get the affect you want? Is there some use case, that needs you to use the container but can't have it bound? Have you seen used this feature in another langauge ?
Basically, it sounds like your trying to create a factory but don't want to create a factory. I would check these docs on how to create a factory and I would be your use case would fit perfectly in it. https://github.com/inversify/InversifyJS/blob/master/wiki/factory_injection.md
Hope this helps!
Hi @Dirrk,
Thanks again for taking the time to answer. It's not about wanting a factory or an instance, it's more about that I don't find necessary to bind just to execute a get
.
In my use case, I'm loading classes at runtime (like plugins), these classes are @injectable
so I'm using the container to create the instances, but I don't have any particular interest in binding them to the container.
Perhaps there's another way to structure the application, for example loading and binding the classes at startup and using multiInject, but I don't think I should restructure the application just to play nice with inversify
. However I'll keep the idea alive, I may be missing something valuable and I don't see it just yet.
As for if I have seen it in another language. I think it's what Unity does:
public ManagementController(ITenantStore tenantStore)
{
this.tenantStore = tenantStore;
}
var container = new UnityContainer();
container.RegisterType<ITenantStore, TenantStore>();
var controller = container.Resolve<ManagementController>();
@pmoleri, I think this is possible to create. The runtime limitations would be avoided because Resolve could then do the work needed to add it to the container without actually doing it (but still resolve the dependencies). I think its worth creating a new issue referencing the new information you have provided and write some rudimentary examples that you would expect to work using the Ninja / Katana / Sword type examples to keep with the theme.
Hi @Dirrk, I'll create the issue. Thanks for everything.
Currently, as I understand, there's no way to instantiate a class without
@injectable
That seem's a lot of work for a simple (yet common) task. Another point is that not all classes should be
@injectables
, sometimes you just want to create a new instance of the class with automatic injections.It should be a simple task of
Is it possible? If
"emitDecoratorMetadata": true
we can get the types in the constructor... I don't know if TS will emit the type information for non-decorated parameters...thoughts?