Kjetil
Kjetil

Reputation: 21

How can WindsorContainer TypedFactory pass arguments to indirect objects

I know that TypedFactory facility will only pass the given arguments to the object it is resolving. But is there a way to make the same arguments be passed down to all indirect objects being resolved?

I've been trying to do this with a Custom Scope defined as

public class ArgumentPassThrough : IScopeAccessor
    {
        private static IDictionary _args;
        public void Dispose()
        {
            _args = null;
        }

        public ILifetimeScope GetScope(CreationContext context)
        {
            var h = context.Handler;
            if (_args == null)
            {
                _args = context.AdditionalArguments;
            }
            else
            {
                var enumerator = _args.GetEnumerator();
                enumerator.Reset();
                while (enumerator.MoveNext())
                {
                    if (!context.AdditionalArguments.Contains(enumerator.Key))
                    {
                        context.AdditionalArguments.Add(enumerator.Key, enumerator.Value);
                    }
                }
            }

            return new DefaultLifetimeScope();
        }
    }

I have the following class structure:

        public class Child2
        {
            public Child2(Child1 child1)
            {
                Child1 = child1;
            }

            public Child1 Child1 { get; private set; }
        }

        public class Child1
        {
            public Child1()
            {
            }
        }


public class Parent
{
            public Parent(Child1 child1, Child2 child2)
            {
                Child1 = child1;
                Child2 = child2;
            }

            public Child1 Child1 { get; private set; }
            public Child2 Child2 { get; private set; }
    }

    public interface IParentFactory
    {
        Parent Create(Child1 child1);
    }

I register them in the windsorcontainer with:

    public void ScopedFactory()
    {
        _container.Register(

            Component.For<IParentFactory>().AsFactory(),
            Component.For<Parent>().LifestyleScoped<ArgumentPassThrough>(),
            Component.For<Child2>().LifestyleScoped<ArgumentPassThrough>(),

            Classes.FromThisAssembly().Pick()
                   .WithService.Self()
                   .LifestyleTransient()
            );
    }

and I'm using it like:

    [Test]
    public void ScopedFactoryDependency()
    {
        _demoModule.ScopedFactory();
        var fac = _container.Resolve<IParentFactory>();

        var p1 = AssertPassThrough(fac);
        var p2 = AssertPassThrough(fac);
        Assert.AreNotSame(p1,p2);
    }

    private Parent AssertPassThrough(IParentFactory fac)
    {
        Parent parent;
        var c1 = _container.Resolve<Child1>();
        using (_container.BeginScope())
        {
            parent = fac.Create(c1);
            Assert.AreSame(parent.Child1, c1);
            Assert.AreSame(parent.Child2.Child1, c1);
        }
        return parent;
    }

The first pass works, but I was expecting the ScopeAccesor to be disposed when _contaier.BeginScope() exists the using block. This dosen't happen, and the second pass will get the same arguments as the first.

Upvotes: 1

Views: 194

Answers (0)

Related Questions