VContainer
VContainer copied to clipboard
Support for Container.Instantiate<T>(parameters)
I would like to be able to instantiate simple C# classes with all dependencies from the current scope injected automatically + some custom parameters. Right now I'm really missing something similar to PlaceholderFactory from Zenject.
Same as this: https://github.com/hadashiA/VContainer/issues/54
Unfortunately Container.Inject allows injecting only instances.
@revolt3r Hello! I have managed to resolve instances with the following extension method:
public static class VContainerExtensions
{
public static T ResolveInstance<T>(this IObjectResolver resolver) =>
(T)resolver.Resolve(new RegistrationBuilder(typeof(T), Lifetime.Transient).Build());
}
My example code that uses this extension:
builder.Register<IInitializationStateMachine>(resolver => InitializationStateMachine.Builder
.Add(resolver.ResolveInstance<LoginState>())
.Add(resolver.ResolveInstance<LoadMainMenuState>())
.Build(),
Lifetime.Scoped);
It works for me and I think you can change this code to support your custom parameters
A small note to the answer above:
You can get access to all types except for the type you are in:
public class MyService
{
public class MyService(Service s) { }
}
public class Service
{
public Service(this IObjectResolver resolver) =>
s.ResolveInstance<MyService>(); //error, the `Service` not yet registered, method injection not working too
}
Instead you should register this
as a parameter:
public static T ResolveInstance<T, TParam>(this IObjectResolver resolver, TParam parameter)
{
var registrationBuilder = new RegistrationBuilder(typeof(T), Lifetime.Transient);
registrationBuilder.WithParameter(parameter);
return (T)resolver.Resolve(registrationBuilder.Build());
}
public class Service
{
public Service(this IObjectResolver resolver) =>
s.ResolveInstance<MyService, Service>(this);
}
Up.
I've come from Zenject and have been using such feature a lot. Especially in conjunction with IInstatiator (instead of using DiContainer directly).
@hadashiA, is it hard to implement? Do we have some workaround for that (ideally, without heap allocations)?
I have considered this issue several times. For me, the main goal of this project was to create the right constraints that would not allow DI to be abused. As a matter of fact, that's why I don't put this feature in. You can inject a container, register it with a lambda expression that receives the container, or write a factory using the lambda expression that receives the container.
I found VContainer's extensibility to be sufficient. I'm not going to implement it unless I come up with a more specific and useful use case.