示例#1
0
        /// <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;
        }
示例#3
0
 /// <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);
        }
示例#6
0
        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);
            });
        }
示例#7
0
        /// <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());
 }
示例#11
0
        /// <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));
 }
示例#13
0
        /// <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;
                }
            });
        }
示例#14
0
        /// <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);
            });
        }
示例#15
0
        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;
 }
示例#17
0
        /// <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)
 {
示例#22
0
        /// <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);
        }
示例#23
0
        /// <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);
        }