JasperFx / lamar

Fast Inversion of Control Tool and Successor to StructureMap
https://jasperfx.github.io/lamar
MIT License
563 stars 118 forks source link

Nested containers do not fallback to parent for resolving injectables. #311

Closed worldspawn closed 2 years ago

worldspawn commented 2 years ago

Hi. When resolving injectables the (nested) container doesn't seems to fallback to the parent container if it has no value. I'm not sure how to work around this. Manually resolving each injectable and passing it to the nested container requires too much knowledge of the domain.

var cp = _container.GetInstance<ClaimsPrincipal>();
var nestedContainer = _container.GetNestedContainer();
var ncp = nestedContainer.GetInstance<ClaimsPrincipal>();//null :(
jeremydmiller commented 2 years ago

That's not how "injectable" is supposed to work. The Injectable thing is just like the HttpContextWrapper in ASP.Net Core. It's strictly for scoped lifetimes. You could do something custom I suppose to effect that.

worldspawn commented 2 years ago

Yeah I figured it was by design. Is there anyway for me to ask the container what injectables it has registered?

jeremydmiller commented 2 years ago

You could use IContainer.Model to interrogate that, but first, can you explain what your actual use case is here?

worldspawn commented 2 years ago

I have a scoped factory service that that has a reference to its scoped/nested container. The factory service uses the container to return new instances.

When I ask this factory for an instance I want to create a nested container, add 1 or more injectables relevant to this scenario to the nested container and then return a new instance. This instance receives several services and has a largish dependency chain which ideally includes these injectables.

In trying to do this I've run into problems where some of the services in the dependency chain require injectables added further up in the execution chain and arn't something my factory knows about/should know about. These are services that are extensibility points.

public class Operator : IOperator
    {
        private readonly Scope _container;

        public Operator(Scope container)
        {
            _container = container;
        }

        public IEntityOperator<TEntity> For<TEntity>(OperatorContext context) where TEntity : IEntity, new()
        {
            var nestedContainer = ((Container) _container).GetNestedContainer();
            nestedContainer.Inject(typeof(OperatorContext), context, true);
            return nestedContainer.GetInstance<IEntityOperator<TEntity>>();
        }
    }
worldspawn commented 2 years ago

And I guess I dont want it to be possible for additional instances existing at the same time to be overwriting each others injectables

jeremydmiller commented 2 years ago

To be perfectly honest, I just don't want to have to support this. This is trying to recreate the old StructureMap With() functionality or kind of a poor man's autofactory. The SM With() mechanism was endlessly buggy and caused user problems. The AutoFactory functionality would be nice, and it's still in the backlog.

I'm closing this.