NamedScopeLifetime
Represents a named scope lifetime.
using Stashbox.Registration;
using Stashbox.Resolution;
using Stashbox.Utils;
using System;
using System.Linq.Expressions;
using System.Reflection;
namespace Stashbox.Lifetime
{
public class NamedScopeLifetime : LifetimeDescriptor
{
private static readonly MethodInfo GetScopeValueMethod = typeof(NamedScopeLifetime).GetSingleMethod("GetScopedValue", true);
protected override Expression GetLifetimeAppliedExpression(IContainerContext containerContext, IServiceRegistration serviceRegistration, ResolutionContext resolutionContext, Type resolveType)
{
Func<IResolutionScope, object> factoryDelegate = GetFactoryDelegate(containerContext, serviceRegistration, resolutionContext, resolveType);
if (factoryDelegate == null)
return null;
return GetScopeValueMethod.MakeGenericMethod(resolveType).CallStaticMethod(resolutionContext.CurrentScopeParameter, factoryDelegate.AsConstant(), serviceRegistration.RegistrationId.AsConstant(), serviceRegistration.RegistrationName.AsConstant(Constants.ObjectType), serviceRegistration.RegistrationContext.NamedScopeRestrictionIdentifier.AsConstant());
}
private static TValue GetScopedValue<TValue>(IResolutionScope currentScope, Func<IResolutionScope, object> factory, int scopeId, object sync, object scopeName)
{
IResolutionScope resolutionScope = currentScope;
while (resolutionScope != null && resolutionScope.Name != scopeName) {
resolutionScope = resolutionScope.ParentScope;
}
if (resolutionScope == null)
throw new InvalidOperationException($"""{scopeName}""");
return (TValue)resolutionScope.GetOrAddScopedObject(scopeId, sync, factory);
}
}
}