/// <summary> /// Translates all registrations in <paramref name="services"/> into registered targets in <paramref name="targets"/>. /// </summary> /// <param name="targets">The target container into which the registrations will be added</param> /// <param name="services">The service collection to be registered</param> public static void Populate(this ITargetContainer targets, IServiceCollection services) { if (targets == null) { throw new ArgumentNullException(nameof(targets)); } //register service provider - ensuring that it's marked as unscoped because the lifetimes of //containers which are also scopes are managed by the code that creates them, not by the containers themselves targets.RegisterExpression(context => (IServiceProvider)context, scopeBehaviour: ScopeBehaviour.None); //register scope factory - uses the context as a scope factory (it will choose between the container or //the scope as the actual scope factory that will be used. targets.RegisterExpression(context => new RezolverContainerScopeFactory(context), typeof(IServiceScopeFactory), ScopeBehaviour.None); foreach (var serviceAndTarget in services.Select(s => new { serviceType = s.ServiceType, target = CreateTargetFromService(s) }).Where(st => st.target != null)) { targets.Register(serviceAndTarget.target, serviceAndTarget.serviceType); } }
/// <summary>Registers an <see cref="Rezolver.Targets.ExpressionTarget" /> built from a lambda expression which takes 5 arguments /// and which returns an instance of <typeparamref name="TResult" /></summary> /// <typeparam name="T1">Type of the 1st parameter of the lambda expression.</typeparam> /// <typeparam name="T2">Type of the 2nd parameter of the lambda expression.</typeparam> /// <typeparam name="T3">Type of the 3rd parameter of the lambda expression.</typeparam> /// <typeparam name="T4">Type of the 4th parameter of the lambda expression.</typeparam> /// <typeparam name="T5">Type of the 5th parameter of the lambda expression.</typeparam> /// <typeparam name="TResult">The return type of the lambda expression.</typeparam> /// <param name="targets">Required. The <see cref="ITargetContainer" /> into which the newly created target will be registered</param> /// <param name="lambda">Required. The lambda expression which is to be compiled and executed when an instance is resolved by a container</param> /// <param name="declaredType">Optional. The <see cref="ITarget.DeclaredType" /> of the target to be created /// if different from <typeparamref name="TResult" />. Also overrides the type against which the registration will be made.</param> /// <param name="scopeBehaviour">Scope behaviour for this expression. The default is <see cref="ScopeBehaviour.Implicit"/>, which means /// that that any returned instance will be tracked implicitly by the active scope. If the expression produces a new instance, then /// this or <see cref="ScopeBehaviour.Explicit"/> can be used safely - the choice being whether /// the expression should produce one instance per scope, or should act as a disposable transient object.</param> /// <param name="scopePreference">If <paramref name="scopeBehaviour"/> is not <see cref="ScopeBehaviour.None"/>, then this controls /// the preferred scope for the instance to be tracked. Defaults to <see cref="ScopePreference.Current"/></param> /// <remarks>All arguments to the lambda are injected from the container when compiled and executed</remarks> public static void RegisterExpression <T1, T2, T3, T4, T5, TResult>(this ITargetContainer targets, Expression <Func <T1, T2, T3, T4, T5, TResult> > lambda, Type declaredType = null, ScopeBehaviour scopeBehaviour = ScopeBehaviour.Implicit, ScopePreference scopePreference = ScopePreference.Current) { targets.RegisterExpression((Expression)lambda, declaredType, scopeBehaviour, scopePreference); }