CreationContextScopeAccessor
using Castle.Core;
using Castle.MicroKernel.Context;
using System;
using System.Linq;
using System.Reflection;
namespace Castle.MicroKernel.Lifestyle.Scoped
{
public class CreationContextScopeAccessor : IScopeAccessor, IDisposable
{
private const string ScopeStash = "castle.scope-stash";
private readonly ComponentModel componentModel;
private readonly Func<IHandler[], IHandler> scopeRootSelector;
public CreationContextScopeAccessor(ComponentModel componentModel, Func<IHandler[], IHandler> scopeRootSelector)
{
this.componentModel = componentModel;
this.scopeRootSelector = scopeRootSelector;
}
public void Dispose()
{
}
public ILifetimeScope GetScope(CreationContext context)
{
CreationContext.ResolutionContext selected = context.SelectScopeRoot(scopeRootSelector);
if (selected == null)
throw new InvalidOperationException($"""{componentModel.Name}""");
DefaultLifetimeScope defaultLifetimeScope = (DefaultLifetimeScope)selected.GetContextualProperty("castle.scope-stash");
if (defaultLifetimeScope == null) {
DefaultLifetimeScope newStash = null;
newStash = new DefaultLifetimeScope(new ScopeCache(), delegate(Burden burden) {
if (burden.RequiresDecommission) {
selected.Burden.RequiresDecommission = true;
selected.Burden.GraphReleased += delegate {
newStash.Dispose();
};
}
});
selected.SetContextualProperty("castle.scope-stash", newStash);
defaultLifetimeScope = newStash;
}
return defaultLifetimeScope;
}
public static IHandler DefaultScopeRootSelector<TBaseForRoot>(IHandler[] resolutionStack)
{
return resolutionStack.FirstOrDefault((IHandler h) => typeof(TBaseForRoot).GetTypeInfo().IsAssignableFrom(h.ComponentModel.Implementation));
}
public static IHandler NearestScopeRootSelector<TBaseForRoot>(IHandler[] resolutionStack)
{
return resolutionStack.LastOrDefault((IHandler h) => typeof(TBaseForRoot).IsAssignableFrom(h.ComponentModel.Implementation));
}
}
}