/// <summary> /// Builds an expression for the given <paramref name="target"/>. /// </summary> /// <param name="target">The target whose expression is to be built.</param> /// <param name="context">The compilation context.</param> /// <param name="compiler">The expression compiler to be used to build any other expressions for targets /// which might be required by the <paramref name="target" />. Note that unlike on the interface, where this /// parameter is optional, this will always be provided</param> protected override Expression Build(SingletonTarget target, IExpressionCompileContext context, IExpressionCompiler compiler) { var holder = context.ResolveContext.Resolve <SingletonTarget.SingletonContainer>(); int? targetIdOverride = context.GetOption <TargetIdentityOverride>(context.TargetType ?? target.DeclaredType); TypeAndTargetId id = new TypeAndTargetId(context.TargetType ?? target.DeclaredType, targetIdOverride ?? target.Id); var lazy = holder.GetLazy(id); if (lazy == null) { lazy = holder.GetLazy( target, id, compiler.CompileTargetStrong( target.InnerTarget, context.NewContext( context.TargetType ?? target.DeclaredType, // this override is important - when forcing into the root-scope, as we do // for singletons, 'explicit' means absolutely nothing. So, instead of allowing // our child target to choose, we explicitly ensure that all instances are implicitly // tracked within the root scope, if it is one which can track instances. scopeBehaviourOverride: ScopeBehaviour.Implicit, scopePreferenceOverride: ScopePreference.Root)), context); } return(Expression.Call( Expression.Constant(lazy), lazy.GetType().GetMethod("Resolve"), context.ResolveContextParameterExpression)); }