Reputation: 21
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