Skip to content
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

Expected override behaviour not working with scopes in 3.1 prerelease 536 #80

Closed
Tobriand opened this issue May 13, 2020 · 3 comments
Closed
Assignees
Labels

Comments

@Tobriand
Copy link

Tobriand commented May 13, 2020

Hi,

When I use the preview version of stashbox (appreciate this may be on your radar and just not final therefore), I'm getting some very strange behaviour when working with scopes:

[TestMethod]
        public void RegisteredInstancesCanBeOverridenViaAFactory()
        {
            // Expectation is that
            // - A registration can be set up that will provide a default value
            // - Scoped instances will override the registration when they have been added.

            //var sbc = CreateContainer(c => c.WithScopedLifetime());
            var sbc = new StashboxContainer(c => c.WithUnknownTypeResolution());
            var toInclude = Args<IFoo>.Get(20);

            // Try using a factory (original scenario)
            //  - ScanScopesFor is an extension method that relies on GetScopedInstanceOrDefault(). It no longer works because the method no longer exists.
            //  - Idea was to walk each IResolutionScope and defer to the default value only if no value was identified, meaning that resolution
            //      could take place without risk of a stackoverflow
            //sbc.Register(toInclude.GetType(), c => c.WithFactory(dr => dr.ScanScopesFor(toInclude.GetType(), null, null).item ?? toInclude));

            // Try just registering a default type
            //  - Below should be equivalent (I think)
            //  - Idea would be to defer to StashBox, and rely on the notion that it would walk the scope-hierarchy for me, 
            //      and fall back on the registration ONLY IF no scoped instance identified
            //  - Actual: Registration used under all circumstances. PutInstanceInScope instance appears to be ignored.
            //sbc.Register(toInclude.GetType(), c => c.WithInstance(toInclude));
            sbc.RegisterInstance(toInclude.GetType(), toInclude);

            // Try placing the instance into the scope at the top layer
            //  - Outer resolves to the expected class, but inner1/2 both resolve to the equivalent of new Args();
            //sbc.PutInstanceInScope(toInclude.GetType(), toInclude);

            var outer = sbc.Resolve<Args<IFoo>>();
            Args<IFoo> inner1 = null;
            Args<IFoo> inner2 = null;
            using (var scope = sbc.BeginScope())
            {
                inner1 = scope.Resolve<Args<IFoo>>();
                var toOverride = Args<IFoo>.Get(30);
                scope.PutInstanceInScope(typeof(Args<IFoo>), toOverride);
                inner2 = scope.Resolve<Args<IFoo>>();
            }

            Assert.AreEqual(toInclude.ArgList[0], outer.ArgList[0]);
            Assert.AreEqual(toInclude.ArgList[0], inner1.ArgList[0]);
            Assert.AreEqual(30, inner2.ArgList[0]);
        }

Am I missing something and this is actually the expected behaviour when operating in a scope (in which case what should I be doing instead to get a scenario where I get access to container registrations, but can locally override), or should at least one of these work?

@Tobriand Tobriand changed the title Expected override behaviour not working with scopes in 3.1 prerelease Expected override behaviour not working with scopes in 3.1 prerelease 536 May 13, 2020
@z4kn4fein
Copy link
Owner

z4kn4fein commented May 14, 2020

Hi,

Ah yeah, I think I know what is going on here. The issue is that the first resolution creates and caches the factory delegate to serve your instance, however, this cache is not going to be invalidated when you put something into the scope to override services. I'm going to fix that and let you know when the next pre-release is ready.

Thanks for reporting!

@z4kn4fein z4kn4fein self-assigned this May 20, 2020
@z4kn4fein z4kn4fein added the bug label May 20, 2020
@z4kn4fein z4kn4fein added this to the v3.1.0 milestone May 20, 2020
z4kn4fein added a commit that referenced this issue May 23, 2020
@z4kn4fein
Copy link
Owner

Hey,
I published a new pre-release version where this functionality should work properly, could you please give it a try? Thanks!

@z4kn4fein z4kn4fein modified the milestones: v3.1.0, v3.1.1 Jun 9, 2020
@z4kn4fein
Copy link
Owner

Closing due to inactivity, feel free to reopen this, or create a new issue when something related comes up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants