By implementing your custom IScopeAccessor
you can create different types of scopes. For the following example I have the two classes Foo
and Bar
in which Bar
will be registered with a custom LifeStyle
.
Each have an Id to assist with testing
public class Foo
{
public Guid FooId { get; } = Guid.NewGuid();
}
public class Bar
{
public Guid BarId { get; } = Guid.NewGuid();
}
To register Bar
as a LifestyleScoped<T>
I implemented FooScopeAccessor
:
public class FooScopeAccessor : IScopeAccessor
{
private static readonly ConcurrentDictionary<Foo, ILifetimeScope> collection = new ConcurrentDictionary<Foo, ILifetimeScope>();
public ILifetimeScope GetScope(CreationContext context)
{
return collection.GetOrAdd(context.AdditionalArguments["scope"] as Foo, new DefaultLifetimeScope());
}
public void Dispose()
{
foreach (var scope in collection)
{
scope.Value.Dispose();
}
collection.Clear();
}
}
Registering and Resolving:
WindsorContainer container = new WindsorContainer();
container.Register(Component.For<Foo>().LifestyleTransient());
var foo1 = container.Resolve<Foo>(); // FooId = 004350ac-40ff-4d1a-8022-7977f94eb418
var foo2 = container.Resolve<Foo>(); // FooId = 714aad8a-e4a2-4950-9017-e387c1c56133
container.Register(Component.For<Bar>().LifestyleScoped<FooScopeAccessor>());
var bar1 = container.Resolve<Bar>(new Dictionary<string, Foo> { ["scope"] = foo1 });
// c144ba90-ce37-45c2-89d4-593d127fb723
var bar2 = container.Resolve<Bar>(new Dictionary<string, Foo> { ["scope"] = foo1 });
// c144ba90-ce37-45c2-89d4-593d127fb723
var bar3 = container.Resolve<Bar>(new Dictionary<string, Foo> { ["scope"] = foo2 });
// bcfe7ba4-cfb3-4b6e-8ecc-a3a3e5055bea
var bar4 = container.Resolve<Bar>(new Dictionary<string, Foo> { ["scope"] = foo1 });
// c144ba90-ce37-45c2-89d4-593d127fb723
As seen above bar1
, bar2
and bar3
which were Resolved using Foo1
are all reference to the same object while bar4
has been Resolved with a new instance of Bar
For more details about implementing a custom IScopeAccessor
refer to Castle's Documentation