Grace icon indicating copy to clipboard operation
Grace copied to clipboard

RecursiveLocateException with factory injection

Open mythteria opened this issue 2 years ago • 1 comments

Hi! I am migrating from autofac to grace ioc and ran into an issue. Suppose such a structure (simplified):

class AService
{
    private readonly Func<ADependency> _func;

    public AService(Func<ADependency> func) =>
        _func = func;

    public ADependency GetDependency() =>
        _func();
}

class ADependency
{
    public ADependency(AService a)
    {
    }
}

Autofac registration works fine:

var autofacContainerBuilder = new ContainerBuilder();
autofacContainerBuilder.RegisterType<ADependency>();
autofacContainerBuilder.RegisterType<AService>();
var autofacContainer = autofacContainerBuilder.Build();
var s1 = autofacContainer.Resolve<AService>();

Unfortunately, when i port it to grace, i got a RecursiveLocateException:

var graceContainer = new DependencyInjectionContainer();
graceContainer.Configure(c =>
{
    c.Export<ADependency>();
    c.Export<AService>(); // throws!
    // c.ExportFactory<IExportLocatorScope, AService>(scope => new AService(scope.Locate<Func<ADependency>>())); // work
});
var s2 = graceContainer.Locate<AService>();

I found a workaround (commented), but it looks rather ugly. Is there a more elegant way to solve this problem?

mythteria avatar Jan 27 '23 19:01 mythteria

Hi! I hope this issue is still relevant.

From the example you've provided, it seems like Grace is trying to build a dependency graph based on the constructor parameters but it encounters circular dependencies. Autofac works in a completely different way under the hood and so you are not facing this kind of problem with it. Workaround is functioning because you are giving direct instructions on how the AService factory should work. So, Grace is not trying to build it for you.

If you can provide a more detailed explanation of the behavior you want to achieve I could help you to get around it.

Do you need any of those services to be a singleton? Or do you expect Each call to GetDependency to create new instances of ADependency together with AService?

Lex45x avatar Aug 14 '23 10:08 Lex45x