/// <summary> /// Initializes a new instance of the <see cref="ComponentRegistration"/> class. /// </summary> /// <param name="id">Unique identifier for the component.</param> /// <param name="activator">Activator used to activate instances.</param> /// <param name="lifetime">Determines how the component will be associated with its lifetime.</param> /// <param name="sharing">Whether the component is shared within its lifetime scope.</param> /// <param name="ownership">Whether the component instances are disposed at the end of their lifetimes.</param> /// <param name="pipelineBuilder">The resolve pipeline builder for the registration.</param> /// <param name="services">Services the component provides.</param> /// <param name="metadata">Data associated with the component.</param> /// <param name="options">The additional registration options.</param> public ComponentRegistration( Guid id, IInstanceActivator activator, IComponentLifetime lifetime, InstanceSharing sharing, InstanceOwnership ownership, IResolvePipelineBuilder pipelineBuilder, IEnumerable <Service> services, IDictionary <string, object?> metadata, RegistrationOptions options = RegistrationOptions.None) { if (services == null) { throw new ArgumentNullException(nameof(services)); } Id = id; Activator = activator ?? throw new ArgumentNullException(nameof(activator)); Lifetime = lifetime ?? throw new ArgumentNullException(nameof(lifetime)); Sharing = sharing; Ownership = ownership; _lateBuildPipeline = pipelineBuilder; Services = Enforce.ArgumentElementNotNull(services, nameof(services)); Metadata = metadata ?? throw new ArgumentNullException(nameof(metadata)); Options = options; }
/// <summary> /// Initializes a new instance of the <see cref="OpenGenericDecoratorRegistrationSource"/> class. /// </summary> /// <param name="registrationData">The registration data for the open generic.</param> /// <param name="existingPipelineBuilder">The pipeline for the existing open generic registration.</param> /// <param name="activatorData">The activator data.</param> public OpenGenericDecoratorRegistrationSource( RegistrationData registrationData, IResolvePipelineBuilder existingPipelineBuilder, OpenGenericDecoratorActivatorData activatorData) { if (registrationData == null) { throw new ArgumentNullException(nameof(registrationData)); } if (activatorData == null) { throw new ArgumentNullException(nameof(activatorData)); } OpenGenericServiceBinder.EnforceBindable(activatorData.ImplementationType, registrationData.Services); if (registrationData.Services.Contains((Service)activatorData.FromService)) { throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, OpenGenericDecoratorRegistrationSourceResources.FromAndToMustDiffer, activatorData.FromService)); } _registrationData = registrationData; _activatorData = activatorData; _existingPipeline = existingPipelineBuilder; }
/// <summary> /// Create an IComponentRegistration from data. /// </summary> /// <param name="id">Id of the registration.</param> /// <param name="data">Registration data.</param> /// <param name="activator">Activator.</param> /// <param name="pipelineBuilder">The component registration's resolve pipeline builder.</param> /// <param name="services">Services provided by the registration.</param> /// <returns>An IComponentRegistration.</returns> public static IComponentRegistration CreateRegistration( Guid id, RegistrationData data, IInstanceActivator activator, IResolvePipelineBuilder pipelineBuilder, Service[] services) { return(CreateRegistration(id, data, activator, pipelineBuilder, services, null)); }
/// <summary> /// Initializes a new instance of the <see cref="OpenGenericDelegateRegistrationSource"/> class. /// </summary> /// <param name="registrationData">The registration data for the open generic.</param> /// <param name="existingPipelineBuilder">The pipeline for the existing open generic registration.</param> /// <param name="activatorData">The activator data.</param> public OpenGenericDelegateRegistrationSource( RegistrationData registrationData, IResolvePipelineBuilder existingPipelineBuilder, OpenGenericDelegateActivatorData activatorData) { _registrationData = registrationData ?? throw new ArgumentNullException(nameof(registrationData)); _existingPipelineBuilder = existingPipelineBuilder; _activatorData = activatorData ?? throw new ArgumentNullException(nameof(activatorData)); }
/// <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="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, Action <ResolveRequestContext, Action <ResolveRequestContext> > callback) { if (builder is null) { throw new ArgumentNullException(nameof(builder)); } builder.Use(new DelegateMiddleware(descriptor, phase, callback), MiddlewareInsertionMode.EndOfPhase); return(builder); }
private void RegistrationPipelineBuilding(object sender, IResolvePipelineBuilder pipeline) { pipeline.Use(PipelinePhase.Activation, MiddlewareInsertionMode.EndOfPhase, (c, next) => { c.ChangeParameters(c.Parameters.Union(new[] { new ResolvedParameter( (p, i) => p.ParameterType == typeof(ILogger), (p, i) => new Log4Net(p.Member.DeclaringType) ) })); next(c); }); }
/// <summary> /// Initializes a new instance of the <see cref="ComponentRegistration"/> class. /// </summary> /// <param name="id">Unique identifier for the component.</param> /// <param name="activator">Activator used to activate instances.</param> /// <param name="lifetime">Determines how the component will be associated with its lifetime.</param> /// <param name="sharing">Whether the component is shared within its lifetime scope.</param> /// <param name="ownership">Whether the component instances are disposed at the end of their lifetimes.</param> /// <param name="pipelineBuilder">The resolve pipeline builder for the registration.</param> /// <param name="services">Services the component provides.</param> /// <param name="metadata">Data associated with the component.</param> /// <param name="target">The component registration upon which this registration is based.</param> /// <param name="options">Registration options.</param> public ComponentRegistration( Guid id, IInstanceActivator activator, IComponentLifetime lifetime, InstanceSharing sharing, InstanceOwnership ownership, IResolvePipelineBuilder pipelineBuilder, IEnumerable <Service> services, IDictionary <string, object?> metadata, IComponentRegistration target, RegistrationOptions options = RegistrationOptions.None) : this(id, activator, lifetime, sharing, ownership, pipelineBuilder, services, metadata, options) { _target = target ?? throw new ArgumentNullException(nameof(target)); // Certain flags carry over from the target. Options = options | (_target.Options & OptionsCopiedFromTargetRegistration); }
/// <summary> /// Initializes a new instance of the <see cref="OpenGenericRegistrationSource"/> class. /// </summary> /// <param name="registrationData">The registration data for the open generic.</param> /// <param name="existingPipelineBuilder">The pipeline for the existing open generic registration.</param> /// <param name="activatorData">The activator data.</param> public OpenGenericRegistrationSource( RegistrationData registrationData, IResolvePipelineBuilder existingPipelineBuilder, ReflectionActivatorData activatorData) { if (registrationData == null) { throw new ArgumentNullException(nameof(registrationData)); } if (activatorData == null) { throw new ArgumentNullException(nameof(activatorData)); } OpenGenericServiceBinder.EnforceBindable(activatorData.ImplementationType, registrationData.Services); _registrationData = registrationData; _existingPipelineBuilder = existingPipelineBuilder; _activatorData = activatorData; }
/// <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="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, Action <ResolveRequestContext, Action <ResolveRequestContext> > callback) { builder.Use(phase, MiddlewareInsertionMode.EndOfPhase, callback); return(builder); }
private void RegistrationPipelineBuilding(object sender, IResolvePipelineBuilder builder) { builder.Use(new PropertyAutoWriteMiddleware()); }
/// <inheritdoc/> public void ProvideMiddleware(Service service, IComponentRegistryServices availableServices, IResolvePipelineBuilder pipelineBuilder) { if (service is IServiceWithType swt) { var closedDecoratorService = new DecoratorService(swt.ServiceType, _decoratorService.Condition); // Try to bind to the service. if (OpenGenericServiceBinder.TryBindOpenGenericTypedService(closedDecoratorService, _registrationData.Services, _activatorData.ImplementationType, out var constructedImplementationType, out var services)) { // Create a new closed-generic registration. var registration = new ComponentRegistration( Guid.NewGuid(), new ReflectionActivator(constructedImplementationType, _activatorData.ConstructorFinder, _activatorData.ConstructorSelector, _activatorData.ConfiguredParameters, _activatorData.ConfiguredProperties), _registrationData.Lifetime, _registrationData.Sharing, _registrationData.Ownership, services, _registrationData.Metadata); // Build the resolve pipeline so we can invoke it. registration.BuildResolvePipeline(availableServices); // Add our closed decorator middleware to the pipeline. pipelineBuilder.Use(new DecoratorMiddleware(closedDecoratorService, registration), MiddlewareInsertionMode.StartOfPhase); } } }
/// <inheritdoc/> public void ProvideMiddleware(Service service, IComponentRegistryServices availableServices, IResolvePipelineBuilder pipelineBuilder) { pipelineBuilder.UseRange(_componentRegistry.ServiceMiddlewareFor(service)); }
/// <inheritdoc/> public void ConfigurePipeline(IComponentRegistryServices componentRegistryServices, IResolvePipelineBuilder pipelineBuilder) { pipelineBuilder.Use(PipelinePhase.Activation, (ctxt, next) => { var pool = (ObjectPool <TLimit>)ctxt.ResolveService(_poolService); var didGetFromPool = false; TLimit PoolGet() { didGetFromPool = true; return(pool.Get()); } var poolItem = _registrationPolicy.Get(ctxt, ctxt.Parameters, PoolGet); if (poolItem is null) { throw new InvalidOperationException( string.Format( CultureInfo.CurrentCulture, PoolGetActivatorResources.PolicyMustReturnInstance, _registrationPolicy.GetType().FullName, typeof(TLimit).FullName)); } if (didGetFromPool) { if (poolItem is IPooledComponent poolAwareComponent) { poolAwareComponent.OnGetFromPool(ctxt, ctxt.Parameters); } // Need to return a 'container' that // gets unpacked just after we're done sharing. // That way disposal of the scope will return to the pool. ctxt.Instance = new PooledInstanceTracker <TLimit>(pool, poolItem); } else { // Instance did not come from the pool, so just use it directly. ctxt.Instance = poolItem; } }); }
/// <inheritdoc/> public void ConfigurePipeline(IComponentRegistryServices componentRegistryServices, IResolvePipelineBuilder pipelineBuilder) { if (componentRegistryServices is null) { throw new ArgumentNullException(nameof(componentRegistryServices)); } if (pipelineBuilder is null) { throw new ArgumentNullException(nameof(pipelineBuilder)); } // Locate the possible constructors at container build time. var availableConstructors = ConstructorFinder.FindConstructors(_implementationType); if (availableConstructors.Length == 0) { throw new NoConstructorsFoundException(_implementationType, string.Format(CultureInfo.CurrentCulture, ReflectionActivatorResources.NoConstructorsAvailable, _implementationType, ConstructorFinder)); } var binders = new ConstructorBinder[availableConstructors.Length]; for (var idx = 0; idx < availableConstructors.Length; idx++) { binders[idx] = new ConstructorBinder(availableConstructors[idx]); } _constructorBinders = binders; pipelineBuilder.Use(ToString(), PipelinePhase.Activation, MiddlewareInsertionMode.EndOfPhase, (ctxt, next) => { ctxt.Instance = ActivateInstance(ctxt, ctxt.Parameters); next(ctxt); }); }
public void ProvideMiddleware(Service service, IComponentRegistryServices availableServices, IResolvePipelineBuilder pipelineBuilder) { pipelineBuilder.Use(PipelinePhase.ServicePipelineEnd, (context, next) => { next(context); object?instance = context.Instance; if (instance != null) { TypeInfo instanceType = instance.GetType().GetTypeInfo(); if (TestDependencyManager.CurrentTestDependencyManager.IsGoingToCreateProxyForImplementationType(instanceType)) { instance = _createProxyForService.MakeGenericMethod(instanceType).Invoke(this, new[] { instance }) !; context.Instance = instance; } TestDependencyManager.CurrentTestDependencyManager.Objects.Add(instance); } }); }
/// <summary> /// Initializes a new instance of the <see cref="ComponentPipelineBuildingArgs"/> class. /// </summary> /// <param name="registration">The registration.</param> /// <param name="pipelineBuilder">The pipeline builder.</param> public ComponentPipelineBuildingArgs(IComponentRegistration registration, IResolvePipelineBuilder pipelineBuilder) { Registration = registration; PipelineBuilder = pipelineBuilder; }
/// <inheritdoc/> public void ConfigurePipeline(IComponentRegistryServices componentRegistryServices, IResolvePipelineBuilder pipelineBuilder) { pipelineBuilder.Use(PipelinePhase.Activation, (context, next) => { // Get a reference to the actual lifetime scope. var scope = context.Resolve <ILifetimeScope>(); var poolPolicy = new AutofacPooledObjectPolicy <TLimit>(_pooledInstanceService, scope, _policy); // The pool provider will create a disposable pool if the TLimit implements IDisposable. var pool = _poolProvider.Create(poolPolicy); context.Instance = pool; }); }
/// <inheritdoc/> protected override IResolvePipeline BuildResolvePipeline(IComponentRegistryServices registryServices, IResolvePipelineBuilder pipelineBuilder) { // Just use the external pipeline. return(Target.ResolvePipeline); }
public void ConfigurePipeline(IComponentRegistryServices componentRegistryServices, IResolvePipelineBuilder pipelineBuilder) { // Should never be invoked. throw new InvalidOperationException(); }
/// <inheritdoc/> public void ProvideMiddleware(Service service, IComponentRegistryServices availableServices, IResolvePipelineBuilder pipelineBuilder) { if (service is IServiceWithType swt && swt.ServiceType == _serviceType) { // This is the right type, add the middleware. pipelineBuilder.Use(_middleware, _insertionMode); } }
private static void RegistrationOnPipelineBuilding(object sender, IResolvePipelineBuilder builder) {
/// <summary> /// Create an IComponentRegistration from data. /// </summary> /// <param name="id">Id of the registration.</param> /// <param name="data">Registration data.</param> /// <param name="activator">Activator.</param> /// <param name="pipelineBuilder">The component registration's resolve pipeline builder.</param> /// <param name="services">Services provided by the registration.</param> /// <param name="target">Optional; target registration.</param> /// <returns>An IComponentRegistration.</returns> /// <exception cref="System.ArgumentNullException"> /// Thrown if <paramref name="activator" /> or <paramref name="data" /> is <see langword="null" />. /// </exception> public static IComponentRegistration CreateRegistration( Guid id, RegistrationData data, IInstanceActivator activator, IResolvePipelineBuilder pipelineBuilder, Service[] services, IComponentRegistration?target) { if (activator == null) { throw new ArgumentNullException(nameof(activator)); } if (data == null) { throw new ArgumentNullException(nameof(data)); } if (pipelineBuilder is null) { throw new ArgumentNullException(nameof(pipelineBuilder)); } if (services == null) { throw new ArgumentNullException(nameof(services)); } var limitType = activator.LimitType; if (limitType != typeof(object)) { foreach (var ts in services) { if (!(ts is IServiceWithType asServiceWithType)) { continue; } if (!asServiceWithType.ServiceType.IsAssignableFrom(limitType)) { throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, RegistrationBuilderResources.ComponentDoesNotSupportService, limitType, ts)); } } } // The pipeline builder fed into the registration is a copy, so that the original builder cannot be edited after the registration has been created, // and the original does not contain any auto-added items. var clonedPipelineBuilder = pipelineBuilder.Clone(); IComponentRegistration registration; if (target == null) { registration = new ComponentRegistration( id, activator, data.Lifetime, data.Sharing, data.Ownership, clonedPipelineBuilder, services, data.Metadata, data.Options); } else { registration = new ComponentRegistration( id, activator, data.Lifetime, data.Sharing, data.Ownership, clonedPipelineBuilder, services, data.Metadata, target, data.Options); } return(registration); }
/// <inheritdoc/> public void ConfigurePipeline(IComponentRegistryServices componentRegistryServices, IResolvePipelineBuilder pipelineBuilder) { if (pipelineBuilder is null) { throw new ArgumentNullException(nameof(pipelineBuilder)); } pipelineBuilder.Use(this.DisplayName(), PipelinePhase.Activation, MiddlewareInsertionMode.EndOfPhase, (ctxt, next) => { ctxt.Instance = ActivateInstance(ctxt, ctxt.Parameters); next(ctxt); }); }
/// <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); }