-
-
Notifications
You must be signed in to change notification settings - Fork 125
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
Resolve enforces passed arguments to be used (and fails because of it) #646
Comments
Hi @cytoph |
Also, from your description:
This behavior is intended and supposed to be working in the v5 and v5.4. But I am not sure how this behavior leads to the specific exception |
I tried to reproduce this with a smaller example, but I'm not able to. All I know is when my project references DryIoc.Microsoft.DependencyInjection 6.0.2 (DryIoc.dll 5.0.2) it works, with DryIoc.Microsoft.DependencyInjection 6.2.0 (DryIoc.dll 5.4.0) it doesn't. I'm still working on an example, but I'm not sure, if I'll be able to provide it. |
@cytoph Could you check if the same issue happens for the latest preview 6.0.0-preview-07? |
@cytoph Did you check with DryIoc v6 preview? |
For what it's worth, I need this feature (pass explicit values to service ctors) so I did a few tests.
@dadhi I was looking for docs on this topic, but I couldn't find any. Is this mentionned somewhere in wiki? My quick tests: using DryIoc;
var container = new Container();
container.Register<Dependency>();
container.Register<Service>();
container.Register<Service2>();
container.Register<DeepService>();
// This fails because ManualArg cannot be injected into Service
Console.WriteLine("Inject Service(dep)");
Console.WriteLine("===================");
try
{
_ = container.Resolve<Service>();
Console.WriteLine("Should have failed?!");
}
catch (ContainerException ex)
{
Console.WriteLine(ex.Message);
}
Console.WriteLine();
Console.WriteLine("Inject Service(dep, arg)");
Console.WriteLine("========================");
// This works by passing the `object[] args` parameters down into Service ctor.
var svc = container.Resolve<Service>([new ManualArg()]);
Console.WriteLine(svc.Dependency.Name);
Console.WriteLine(svc.Arg.Name);
Console.WriteLine();
Console.WriteLine("Inject Service2(dep)");
Console.WriteLine("====================");
// This still works, even though arguments ManualArg() turns out to not be required.
var svc2 = container.Resolve<Service2>([new ManualArg()]);
Console.WriteLine(svc2.Dependency.Name);
Console.WriteLine();
Console.WriteLine("Inject DeepService(arg)");
Console.WriteLine("=======================");
// This demonstrates that ManualArg() will be used deep in the resolution graph, too.
var deep = container.Resolve<DeepService>([new ManualArg()]);
Console.WriteLine(deep.Dependency.Name);
Console.WriteLine();
Console.WriteLine("Inject DeepService(local_svc)");
Console.WriteLine("=============================");
// This demonstrates that registered services are also replaced by provided arguments during resolution
var localSvc = new Service(null!, null!);
var customized = container.Resolve<DeepService>([localSvc]);
Console.WriteLine(ReferenceEquals(customized.Service, localSvc));
class Dependency
{
public string Name => "Dependency";
}
class ManualArg
{
public string Name => "Arg";
}
class Service(Dependency dep, ManualArg arg)
{
public Dependency Dependency => dep;
public ManualArg Arg => arg;
}
class Service2(Dependency dep)
{
public Dependency Dependency => dep;
}
class DeepService(Service svc)
{
public Service Service => svc;
public Dependency Dependency => svc.Dependency;
} |
Noted. |
I did one more test, because I don't want to use // Added to my code from previous comment:
Console.WriteLine();
Console.WriteLine("Inject factory Func<ManualArg, Service>");
Console.WriteLine("=======================================");
// This demonstrates a factory that accepts an argument
var fn = container.Resolve<Func<ManualArg, Service>>();
svc = fn(new ManualArg());
Console.WriteLine(svc.Dependency.Name); |
@jods4 After quick check, I did not find the documentation for the args as well. Though you test cases display the design as intended:
Here is an open issue/feature, adding more control on what services are replaced with args: #222 |
@dadhi No worry! Thanks! |
I just updated DryIoc from version 5.0.2 to 5.4.0 and an error starts occurring (of which I could not find anything in breaking changes or such). The error occurs on calling
container.Resolve(serviceType, [service])
.service
is, in this case, a service instance that I want to be passed to theserviceType
constructor in place of the instance that is registered in the container (that's why I pass it). This worked fine before the update. Now, on version 5.4.0, I get an exception, because the container tries to pass this service instance to every other (undelying) service that is resolved during this call, and not just that, it forces it to be present in every constructor, it seems, which leads to the following exception:I didn't change anything on the containers rules or such. Is there a new rule or parameter that's now set by default, that I must explicitly disable to get this to work again?
The text was updated successfully, but these errors were encountered: