/// <inheritdoc/> public IResolvePipelineBuilder Use(IResolveMiddleware stage, MiddlewareInsertionMode insertionMode = MiddlewareInsertionMode.EndOfPhase) { if (stage is null) { throw new ArgumentNullException(nameof(stage)); } AddStage(stage, insertionMode); return(this); }
private void AddStage(IResolveMiddleware stage, MiddlewareInsertionMode insertionLocation) { VerifyPhase(stage.Phase); // Start at the beginning. var currentStage = _first; var newStageDecl = new MiddlewareDeclaration(stage); if (_first is null) { _first = _last = newStageDecl; return; } while (currentStage is object) { if (insertionLocation == MiddlewareInsertionMode.StartOfPhase ? currentStage.Middleware.Phase >= stage.Phase : currentStage.Middleware.Phase > stage.Phase) { if (currentStage.Previous is object) { // Insert the node. currentStage.Previous.Next = newStageDecl; newStageDecl.Next = currentStage; newStageDecl.Previous = currentStage.Previous; currentStage.Previous = newStageDecl; } else { _first.Previous = newStageDecl; newStageDecl.Next = _first; _first = newStageDecl; } return; } currentStage = currentStage.Next; } // Add at the end. newStageDecl.Previous = _last; _last !.Next = newStageDecl; _last = newStageDecl; }
/// <inheritdoc/> public void AddServiceMiddleware(Service service, IResolveMiddleware middleware, MiddlewareInsertionMode insertionMode = MiddlewareInsertionMode.EndOfPhase) { var info = GetServiceInfo(service); info.UseServiceMiddleware(middleware, insertionMode); }
/// <summary> /// Register a resolve middleware for services providing a particular type. /// </summary> /// <typeparam name="TService">The service type.</typeparam> /// <param name="builder">The container builder.</param> /// <param name="middleware">The middleware to register.</param> /// <param name="insertionMode">The insertion mode of the middleware (start or end of phase).</param> public static void RegisterServiceMiddleware <TService>(this ContainerBuilder builder, IResolveMiddleware middleware, MiddlewareInsertionMode insertionMode = MiddlewareInsertionMode.EndOfPhase) { builder.RegisterServiceMiddleware(typeof(TService), middleware, insertionMode); }
/// <summary> /// Register a resolve middleware for a particular service. /// </summary> /// <param name="builder">The container builder.</param> /// <param name="service">The service to register middleware for.</param> /// <param name="middleware">The middleware to register.</param> /// <param name="insertionMode">The insertion mode of the middleware (start or end of phase).</param> public static void RegisterServiceMiddleware(this ContainerBuilder builder, Service service, IResolveMiddleware middleware, MiddlewareInsertionMode insertionMode = MiddlewareInsertionMode.EndOfPhase) { if (builder is null) { throw new ArgumentNullException(nameof(builder)); } if (service is null) { throw new ArgumentNullException(nameof(service)); } if (middleware is null) { throw new ArgumentNullException(nameof(middleware)); } builder.RegisterCallback(crb => crb.RegisterServiceMiddleware(service, middleware, insertionMode)); }
/// <summary> /// Register a resolve middleware for services providing a particular type. /// </summary> /// <param name="builder">The container builder.</param> /// <param name="serviceType">The service type.</param> /// <param name="middleware">The middleware to register.</param> /// <param name="insertionMode">The insertion mode of the middleware (start or end of phase).</param> public static void RegisterServiceMiddleware(this ContainerBuilder builder, Type serviceType, IResolveMiddleware middleware, MiddlewareInsertionMode insertionMode = MiddlewareInsertionMode.EndOfPhase) { if (builder is null) { throw new ArgumentNullException(nameof(builder)); } if (serviceType is null) { throw new ArgumentNullException(nameof(serviceType)); } if (middleware is null) { throw new ArgumentNullException(nameof(middleware)); } builder.RegisterServiceMiddlewareSource(new ServiceWithTypeMiddlewareSource(serviceType, middleware, insertionMode)); }
/// <summary> /// Register a resolve middleware for services providing a particular type. /// </summary> /// <typeparam name="TService">The service type.</typeparam> /// <param name="builder">The container builder.</param> /// <param name="descriptor">A description for the middleware; this will show up in any resolve tracing.</param> /// <param name="phase">The phase of the pipeline the middleware should run at.</param> /// <param name="callback"> /// A callback invoked to run your middleware. /// This callback takes a <see cref="ResolveRequestContext"/>, containing the context for the resolve request, plus /// a callback to invoke to continue the pipeline. /// </param> /// <param name="insertionMode">The insertion mode of the middleware (start or end of phase).</param> public static void RegisterServiceMiddleware <TService>(this ContainerBuilder builder, string descriptor, PipelinePhase phase, MiddlewareInsertionMode insertionMode, Action <ResolveRequestContext, Action <ResolveRequestContext> > callback) { builder.RegisterServiceMiddleware(typeof(TService), new DelegateMiddleware(descriptor, phase, callback), insertionMode); }
/// <inheritdoc/> public void RegisterServiceMiddleware(Service service, IResolveMiddleware middleware, MiddlewareInsertionMode insertionMode = MiddlewareInsertionMode.EndOfPhase) { if (service is null) { throw new ArgumentNullException(nameof(service)); } if (middleware is null) { throw new ArgumentNullException(nameof(middleware)); } _registeredServicesTracker.AddServiceMiddleware(service, middleware, insertionMode); }
/// <summary> /// Use a middleware callback in a resolve pipeline. /// </summary> /// <param name="builder">The container builder.</param> /// <param name="descriptor">A description for the middleware; this will show up in any resolve tracing.</param> /// <param name="phase">The phase of the pipeline the middleware should run at.</param> /// <param name="insertionMode">The insertion mode specifying whether to add at the start or end of the phase.</param> /// <param name="callback"> /// A callback invoked to run your middleware. /// This callback takes a <see cref="ResolveRequestContext"/>, containing the context for the resolve request, plus /// a callback to invoke to continue the pipeline. /// </param> /// <returns>The same builder instance.</returns> public static IResolvePipelineBuilder Use(this IResolvePipelineBuilder builder, string descriptor, PipelinePhase phase, MiddlewareInsertionMode insertionMode, Action <ResolveRequestContext, Action <ResolveRequestContext> > callback) { if (builder is null) { throw new ArgumentNullException(nameof(builder)); } if (descriptor is null) { throw new ArgumentNullException(nameof(descriptor)); } if (callback is null) { throw new ArgumentNullException(nameof(callback)); } builder.Use(new DelegateMiddleware(descriptor, phase, callback), insertionMode); return(builder); }
/// <summary> /// Use a middleware callback in a resolve pipeline. /// </summary> /// <param name="builder">The container builder.</param> /// <param name="phase">The phase of the pipeline the middleware should run at.</param> /// <param name="insertionMode">The insertion mode specifying whether to add at the start or end of the phase.</param> /// <param name="callback"> /// A callback invoked to run your middleware. /// This callback takes a <see cref="ResolveRequestContext"/>, containing the context for the resolve request, plus /// a callback to invoke to continue the pipeline. /// </param> /// <returns>The same builder instance.</returns> public static IResolvePipelineBuilder Use(this IResolvePipelineBuilder builder, PipelinePhase phase, MiddlewareInsertionMode insertionMode, Action <ResolveRequestContext, Action <ResolveRequestContext> > callback) { builder.Use(AnonymousDescriptor, phase, insertionMode, callback); return(builder); }
/// <summary> /// Initializes a new instance of the <see cref="ServiceWithTypeMiddlewareSource"/> class. /// </summary> /// <param name="serviceType">The service type.</param> /// <param name="middleware">The middleware to add.</param> /// <param name="insertionMode">The insertion mode of the middleware.</param> public ServiceWithTypeMiddlewareSource(Type serviceType, IResolveMiddleware middleware, MiddlewareInsertionMode insertionMode) { _serviceType = serviceType ?? throw new ArgumentNullException(nameof(serviceType)); _middleware = middleware ?? throw new ArgumentNullException(nameof(middleware)); _insertionMode = insertionMode; }
/// <inheritdoc/> public IResolvePipelineBuilder UseRange(IEnumerable <IResolveMiddleware> stages, MiddlewareInsertionMode insertionMode = MiddlewareInsertionMode.EndOfPhase) { if (stages is null) { throw new ArgumentNullException(nameof(stages)); } // Use multiple stages. // Start at the beginning. var currentStage = _first; using var enumerator = stages.GetEnumerator(); if (!enumerator.MoveNext()) { return(this); } var nextNewStage = enumerator.Current; var lastPhase = nextNewStage.Phase; VerifyPhase(nextNewStage.Phase); while (currentStage is object) { if (insertionMode == MiddlewareInsertionMode.StartOfPhase ? currentStage.Middleware.Phase >= nextNewStage.Phase : currentStage.Middleware.Phase > nextNewStage.Phase) { var newDecl = new MiddlewareDeclaration(enumerator.Current); if (currentStage.Previous is object) { // Insert the node. currentStage.Previous.Next = newDecl; newDecl.Next = currentStage; newDecl.Previous = currentStage.Previous; currentStage.Previous = newDecl; } else { _first !.Previous = newDecl; newDecl.Next = _first; _first = newDecl; } currentStage = newDecl; if (!enumerator.MoveNext()) { // Done. return(this); } nextNewStage = enumerator.Current; VerifyPhase(nextNewStage.Phase); if (nextNewStage.Phase < lastPhase) { throw new InvalidOperationException(ResolvePipelineBuilderMessages.MiddlewareMustBeInPhaseOrder); } lastPhase = nextNewStage.Phase; } currentStage = currentStage.Next; } do { nextNewStage = enumerator.Current; VerifyPhase(nextNewStage.Phase); if (nextNewStage.Phase < lastPhase) { throw new InvalidOperationException(ResolvePipelineBuilderMessages.MiddlewareMustBeInPhaseOrder); } lastPhase = nextNewStage.Phase; var newStageDecl = new MiddlewareDeclaration(nextNewStage); if (_last is null) { _first = _last = newStageDecl; } else { newStageDecl.Previous = _last; _last.Next = newStageDecl; _last = newStageDecl; } }while (enumerator.MoveNext()); return(this); }