コード例 #1
0
        RegisterCollection <T>(ContainerBuilder builder, string collectionName, Type elementType)
        {
            if (builder == null)
            {
                throw new ArgumentNullException("builder");
            }
            if (elementType == null)
            {
                throw new ArgumentNullException("elementType");
            }
            Enforce.ArgumentNotNullOrEmpty(collectionName, "collectionName");

            var arrayType = elementType.MakeArrayType();
            var ts        = new TypedService(elementType);

            var activator = new DelegateActivator(arrayType, (c, p) =>
            {
                var elements = GetElementRegistrations(collectionName, c.ComponentRegistry);
                var items    = elements.Select(e => c.ResolveComponent(ts, e, p)).ToArray();

                var result = Array.CreateInstance(elementType, items.Length);
                items.CopyTo(result, 0);
                return(result);
            });

            var rb = new RegistrationBuilder <T[], SimpleActivatorData, SingleRegistrationStyle>(
                new TypedService(typeof(T[])),
                new SimpleActivatorData(activator),
                new SingleRegistrationStyle());

            builder.RegisterCallback(cr => RegistrationBuilder.RegisterSingleComponent(cr, rb));

            return(rb);
        }
コード例 #2
0
        public void WhenActivationDelegateReturnsNull_ExceptionDescribesLimitType()
        {
            var target = new DelegateActivator(typeof(string), (c, p) => null);

            var ex = Assert.Throws <DependencyResolutionException>(
                () => target.ActivateInstance(new ContainerBuilder().Build(), Enumerable.Empty <Parameter>()));

            Assert.Contains(typeof(string).ToString(), ex.Message);
        }
コード例 #3
0
        public void ActivateInstance_ReturnsResultOfInvokingSuppliedDelegate()
        {
            var instance = new object();

            var target =
                new DelegateActivator(typeof(object), (c, p) => instance);

            Assert.Same(instance, target.ActivateInstance(new ContainerBuilder().Build(), Enumerable.Empty <Parameter>()));
        }
コード例 #4
0
        public void WhenActivationDelegateReturnsNull_ExceptionDescribesLimitType()
        {
            var target = new DelegateActivator(typeof(string), (c, p) => null);

            var container = Factory.CreateEmptyContainer();
            var invoker   = target.GetPipelineInvoker(container.ComponentRegistry);

            var ex = Assert.Throws <DependencyResolutionException>(
                () => invoker(container, Factory.NoParameters));

            Assert.Contains(typeof(string).ToString(), ex.Message);
        }
コード例 #5
0
        public void Pipeline_ReturnsResultOfInvokingSuppliedDelegate()
        {
            var instance = new object();

            var target =
                new DelegateActivator(typeof(object), (c, p) => instance);

            var container = Factory.CreateEmptyContainer();
            var invoker   = target.GetPipelineInvoker(container.ComponentRegistry);

            Assert.Same(instance, invoker(container, Factory.NoParameters));
        }
コード例 #6
0
        public IEnumerable <IComponentRegistration> RegistrationsFor(Service service, Func <Service, IEnumerable <IComponentRegistration> > registrationAccessor)
        {
            if (!(service is IServiceWithType swt) || !IsGenericSingleType(swt.ServiceType))
            {
                return(Enumerable.Empty <IComponentRegistration>());
            }

            var serviceType        = swt.ServiceType;
            var elementType        = serviceType.GetTypeInfo().GenericTypeArguments.First();
            var singleResolverType = typeof(SingleResolver <>).MakeGenericType(elementType);
            var elementTypeService = swt.ChangeType(elementType);

            var activator = new DelegateActivator(
                serviceType,
                (c, p) =>
            {
                var elements = c.ComponentRegistry.RegistrationsFor(elementTypeService).ToList();
                if (elements.IsNullOrEmpty())
                {
                    return(Activator.CreateInstance(singleResolverType, false, null));
                }

                var item = elements.Select(cr => c.ResolveComponent(cr, p)).Single();
                return(Activator.CreateInstance(singleResolverType, true, item));
            });

            var registration = new ComponentRegistration(
                Guid.NewGuid(),
                activator,
                new CurrentScopeLifetime(),
                InstanceSharing.None,
                InstanceOwnership.ExternallyOwned,
                new[] { service },
                new Dictionary <string, object>());

            return(new IComponentRegistration[] { registration });
        }
コード例 #7
0
        public static IRegistrationBuilder <T[], SimpleActivatorData, SingleRegistrationStyle> RegisterCollection <T>(ContainerBuilder builder, string collectionName, Type elementType)
        {
            if (builder == null)
            {
                throw new ArgumentNullException("builder");
            }
            if (elementType == null)
            {
                throw new ArgumentNullException("elementType");
            }
            Enforce.ArgumentNotNullOrEmpty(collectionName, "collectionName");
            DelegateActivator activator = new DelegateActivator(elementType.MakeArrayType(), delegate(IComponentContext c, IEnumerable <Parameter> p) {
                object[] objArray = (from e in GetElementRegistrations(collectionName, c.ComponentRegistry) select c.ResolveComponent(e, p)).ToArray <object>();
                Array array       = Array.CreateInstance(elementType, objArray.Length);
                objArray.CopyTo(array, 0);
                return(array);
            });
            RegistrationBuilder <T[], SimpleActivatorData, SingleRegistrationStyle> rb = new RegistrationBuilder <T[], SimpleActivatorData, SingleRegistrationStyle>(new TypedService(typeof(T[])), new SimpleActivatorData(activator), new SingleRegistrationStyle());

            builder.RegisterCallback(delegate(IComponentRegistry cr) {
                RegistrationBuilder.RegisterSingleComponent <T[], SimpleActivatorData, SingleRegistrationStyle>(cr, rb);
            });
            return(rb);
        }
コード例 #8
0
        /// <summary>
        /// Retrieve registrations for an unregistered service, to be used
        /// by the container.
        /// </summary>
        /// <param name="service">The service that was requested.</param>
        /// <param name="registrationAccessor">A function that will return existing registrations for a service.</param>
        /// <returns>Registrations providing the service.</returns>
        public IEnumerable <IComponentRegistration> RegistrationsFor(Service service, Func <Service, IEnumerable <IComponentRegistration> > registrationAccessor)
        {
            if (service == null)
            {
                throw new ArgumentNullException(nameof(service));
            }
            if (registrationAccessor == null)
            {
                throw new ArgumentNullException(nameof(registrationAccessor));
            }

            if (!(service is IServiceWithType swt) || service is DecoratorService)
            {
                return(Enumerable.Empty <IComponentRegistration>());
            }

            var  serviceType = swt.ServiceType;
            Type elementType = null;
            Type limitType   = null;
            Func <IEnumerable <object>, object> generator = null;

            if (serviceType.IsGenericTypeDefinedBy(typeof(IEnumerable <>)))
            {
                elementType = serviceType.GetTypeInfo().GenericTypeArguments.First();
                limitType   = elementType.MakeArrayType();
                generator   = BuildGenerator(elementType, nameof(Enumerable.ToArray));
            }
            else if (serviceType.IsArray)
            {
                elementType = serviceType.GetElementType();
                limitType   = serviceType;
                generator   = BuildGenerator(elementType, nameof(Enumerable.ToArray));
            }
            else if (serviceType.IsGenericListOrCollectionInterfaceType())
            {
                elementType = serviceType.GetTypeInfo().GenericTypeArguments.First();
                limitType   = typeof(List <>).MakeGenericType(elementType);
                generator   = BuildGenerator(elementType, nameof(Enumerable.ToList));
            }

            if (elementType == null || limitType == null || generator == null)
            {
                return(Enumerable.Empty <IComponentRegistration>());
            }

            var elementTypeService = swt.ChangeType(elementType);

            var activator = new DelegateActivator(
                limitType,
                (c, p) =>
            {
                var elements = c.ComponentRegistry.RegistrationsFor(elementTypeService).OrderBy(cr => cr.GetRegistrationOrder());
                var items    = elements.Select(cr => c.ResolveComponent(cr, p));

                return(generator(items));
            });

            var registration = new ComponentRegistration(
                Guid.NewGuid(),
                activator,
                new CurrentScopeLifetime(),
                InstanceSharing.None,
                InstanceOwnership.ExternallyOwned,
                new[] { service },
                new Dictionary <string, object>());

            return(new IComponentRegistration[] { registration });
        }
コード例 #9
0
        /// <summary>
        /// Retrieve registrations for an unregistered service, to be used
        /// by the container.
        /// </summary>
        /// <param name="service">The service that was requested.</param>
        /// <param name="registrationAccessor">A function that will return existing registrations for a service.</param>
        /// <returns>Registrations providing the service.</returns>
        public IEnumerable <IComponentRegistration> RegistrationsFor(Service service, Func <Service, IEnumerable <IComponentRegistration> > registrationAccessor)
        {
            if (service == null)
            {
                throw new ArgumentNullException(nameof(service));
            }
            if (registrationAccessor == null)
            {
                throw new ArgumentNullException(nameof(registrationAccessor));
            }

            var swt = service as IServiceWithType;

            if (swt == null)
            {
                return(Enumerable.Empty <IComponentRegistration>());
            }

            var  serviceType = swt.ServiceType;
            Type elementType = null;

            if (serviceType.IsGenericEnumerableInterfaceType())
            {
                elementType = serviceType.GetTypeInfo().GenericTypeArguments.First();
            }
            else if (serviceType.IsArray)
            {
                elementType = serviceType.GetElementType();
            }

            if (elementType == null)
            {
                return(Enumerable.Empty <IComponentRegistration>());
            }

            var elementTypeService = swt.ChangeType(elementType);
            var elementArrayType   = elementType.MakeArrayType();

            var listType          = typeof(List <>).MakeGenericType(elementType);
            var serviceTypeIsList = serviceType.IsGenericListOrCollectionInterfaceType();

            var activator = new DelegateActivator(
                elementArrayType,
                (c, p) =>
            {
                var elements = c.ComponentRegistry.RegistrationsFor(elementTypeService).OrderBy(cr => cr.GetRegistrationOrder());
                var items    = elements.Select(cr => c.ResolveComponent(cr, p)).ToArray();

                var result = Array.CreateInstance(elementType, items.Length);
                items.CopyTo(result, 0);

                return(serviceTypeIsList ? Activator.CreateInstance(listType, result) : result);
            });

            var registration = new ComponentRegistration(
                Guid.NewGuid(),
                activator,
                new CurrentScopeLifetime(),
                InstanceSharing.None,
                InstanceOwnership.ExternallyOwned,
                new[] { service },
                new Dictionary <string, object>());

            return(new IComponentRegistration[] { registration });
        }
コード例 #10
0
        public IEnumerable<IComponentRegistration> RegistrationsFor(Service service, Func<Service, IEnumerable<ServiceRegistration>> registrationAccessor)
        {
            if (service == null)
            {
                throw new ArgumentNullException(nameof(service));
            }

            if (registrationAccessor == null)
            {
                throw new ArgumentNullException(nameof(registrationAccessor));
            }

            if (!(service is IServiceWithType swt) || service is DecoratorService)
            {
                return Enumerable.Empty<IComponentRegistration>();
            }

            var serviceType = swt.ServiceType;
            Type? elementType = null;
            Type? limitType = null;
            Func<int, IList>? factory = null;

            if (serviceType.IsGenericTypeDefinedBy(typeof(IEnumerable<>)))
            {
                elementType = serviceType.GenericTypeArguments[0];
                limitType = elementType.MakeArrayType();
                factory = GenerateArrayFactory(elementType);
            }
            else if (serviceType.IsArray)
            {
                elementType = serviceType.GetElementType();
                limitType = serviceType;
                factory = GenerateArrayFactory(elementType);
            }
            else if (serviceType.IsGenericListOrCollectionInterfaceType())
            {
                elementType = serviceType.GenericTypeArguments[0];
                limitType = typeof(List<>).MakeGenericType(elementType);
                factory = GenerateListFactory(elementType);
            }

            if (elementType == null || factory == null || limitType == null)
            {
                return Enumerable.Empty<IComponentRegistration>();
            }

            var elementTypeService = swt.ChangeType(elementType);

            var activator = new DelegateActivator(
                limitType,
                (c, p) =>
                {
                    var itemRegistrations = c.ComponentRegistry
                        .ServiceRegistrationsFor(elementTypeService)
                        .Where(cr => !cr.Registration.Options.HasOption(RegistrationOptions.ExcludeFromCollections))
                        .OrderBy(cr => cr.Registration.GetRegistrationOrder())
                        .ToList();

                    var output = factory(itemRegistrations.Count);
                    var isFixedSize = output.IsFixedSize;

                    for (var i = 0; i < itemRegistrations.Count; i++)
                    {
                        var itemRegistration = itemRegistrations[i];
                        var resolveRequest = new ResolveRequest(elementTypeService, itemRegistration, p);
                        var component = c.ResolveComponent(resolveRequest);
                        if (isFixedSize)
                        {
                            output[i] = component;
                        }
                        else
                        {
                            output.Add(component);
                        }
                    }

                    return output;
                });

            var registration = new ComponentRegistration(
                Guid.NewGuid(),
                activator,
                CurrentScopeLifetime.Instance,
                InstanceSharing.None,
                InstanceOwnership.ExternallyOwned,
                new[] { service },
                new Dictionary<string, object?>());

            return new IComponentRegistration[] { registration };
        }
コード例 #11
0
        private static void CreateChildLifetimeContext(IComponentRegistryBuilder componentRegistryBuilder)
        {
            // var setupContainer = componentRegistry ;
#if USEHANDLER
            setupContainer.ResolveOperationBeginning += (sender, args) => {
                args.ResolveOperation.InstanceLookupBeginning += (o, eventArgs) => {
                    eventArgs.InstanceLookup.InstanceLookupEnding +=
                        (sender1, endingEventArgs) => {
                        if (endingEventArgs.NewInstanceActivated)
                        {
                            Logger.Debug("New instance activated");
                        }
                    };
                };
            };
#endif

            var registry = componentRegistry;
            foreach (var componentRegistryRegistration in registry.Registrations)
            {
                if (IsMyRegistration(componentRegistryRegistration))
                {
                    Logger.Warn("is my registration");
                }
                else
                {
                    Logger.Error("is not my registration");
                }

                var seen = new HashSet <object> ( );
                Dump(componentRegistryRegistration, seen);

                if (componentRegistryRegistration.Activator is ReflectionActivator rf)
                {
                    Logger.Debug(rf.LimitType.ToString( ));
                    var x = new DelegateActivator(
                        rf.LimitType
                        , (context, parameters) => {
                        Logger.Debug(
                            "delegate activation of reflection component success."
                            );
                        var r = rf.ActivateInstance(
                            context
                            , parameters
                            );
                        Logger.Debug("got " + r);
                        if (r is IHaveLogger haveLogger)
                        {
                            Logger.Debug(
                                "has IHaveLogger interface."
                                );
                            if (haveLogger.Logger == null)
                            {
                                Logger.Debug(
                                    "logger is null, resolving"
                                    );
                                haveLogger.Logger =
                                    context.Resolve <ILogger> (
                                        new
                                        TypedParameter(
                                            typeof
                                            (Type
                                            )
                                            , r
                                            .GetType( )
                                            )
                                        );
                            }
                        }

                        return(r);
                    }
                        );

                    IComponentRegistration componentRegistration = new ComponentRegistration(
                        Guid
                        .NewGuid( )
                        , x
                        , componentRegistryRegistration
                        .Lifetime
                        , componentRegistryRegistration
                        .Sharing
                        , componentRegistryRegistration
                        .Ownership
                        , componentRegistryRegistration
                        .Services
                        , componentRegistryRegistration
                        .Metadata
                        , componentRegistryRegistration
                        );

                    Logger.Debug("wrapping reflection with delegate");
                    try
                    {
                        registry.Register(componentRegistration);
                    }
                    catch (Exception ex)
                    {
                        Logger.Debug(ex, "failure is " + ex.Message);
                    }
                }
                else if (componentRegistryRegistration.Activator is DelegateActivator d)
                {
                    if (!(d is MyActivator))
                    {
                        if (componentRegistryRegistration.Ownership
                            == InstanceOwnership.ExternallyOwned)
                        {
                            Logger.Debug("Externally owned component registration.");
                        }
                        else
                        {
                            var x = new DelegateActivator(
                                d.LimitType
                                , (context, parameters) => {
                                Logger.Debug("activating !!");
                                var r = d.ActivateInstance(
                                    context
                                    , parameters
                                    );
                                Logger.Debug("got " + r);
                                return(r);
                            }
                                );


                            IComponentRegistration componentRegistration =
                                new ComponentRegistration(
                                    Guid.NewGuid( )
                                    , x
                                    , componentRegistryRegistration.Lifetime
                                    , componentRegistryRegistration.Sharing
                                    , componentRegistryRegistration.Ownership
                                    , componentRegistryRegistration.Services
                                    , componentRegistryRegistration.Metadata
                                    , componentRegistryRegistration
                                    );


                            Logger.Debug("wrapping delegate activator");
                            try
                            {
                                registry.Register(componentRegistration);
                            }
                            catch (Exception ex)
                            {
                                Logger.Debug(ex, "failure is " + ex.Message);
                            }
                        }
                    }
                }

                componentRegistryRegistration.Preparing += (sender, args) => {
                };

                componentRegistryRegistration.Activated += (sender, args) => {
                    Logger.Debug($"Activated {args.Instance}");
                };
            }
        }
コード例 #12
0
        public IEnumerable <IComponentRegistration> RegistrationsFor(
            Autofac.Core.Service service,
            Func <Autofac.Core.Service, IEnumerable <IComponentRegistration> > registrationAccessor)
        {
            if (!(service is IServiceWithType swt))
            {
                return(Enumerable.Empty <IComponentRegistration>());
            }

            // TODO: Need to investigate this, is not the proper solution
            if (service is DecoratorService)
            {
                return(Enumerable.Empty <IComponentRegistration>());
            }

            Type serviceType = swt.ServiceType;

            // Ensure is IEnumerable<IPipelineBehavior<,>>
            if (IsGenericTypeDefined(serviceType, typeof(IEnumerable <>)))
            {
                Type enumerableItemType = serviceType.GetGenericArguments().First();
                if (IsGenericTypeDefined(enumerableItemType, typeof(IPipelineBehavior <,>)))
                {
                    Type[] genericTypes = enumerableItemType.GetGenericArguments();
                    Type   requestType  = genericTypes[0];                             // IQuery<> or ICommand<>
                    Type   responseType = genericTypes[1];                             // IResponse<TResult>
                    Type   resultType   = responseType.GetGenericArguments().Single(); // TResult

                    Autofac.Core.Service closePipeline = swt.ChangeType(typeof(IPipelineBehaviour <, ,>).MakeGenericType(new[] { requestType, responseType, resultType }));

                    var activator = new DelegateActivator(
                        enumerableItemType.MakeArrayType(),
                        (ctx, parameters) =>
                    {
                        IEnumerable <IComponentRegistration> registrations = ctx.ComponentRegistry.RegistrationsFor(closePipeline);
                        IEnumerable <object> instances =
                            registrations
                            .Select(componentRegistration => ctx.ResolveComponent(componentRegistration, parameters))
                            .Reverse()
                            .ToArray();

                        return(OfType(instances, enumerableItemType));
                    }
                        );

                    IComponentRegistration registration = new ComponentRegistration(
                        Guid.NewGuid(),
                        activator,
                        new CurrentScopeLifetime(),
                        InstanceSharing.None,
                        InstanceOwnership.OwnedByLifetimeScope,
                        new[] { service },
                        new Dictionary <string, object>()
                        );

                    return(new IComponentRegistration[] { registration });
                }
            }

            return(Enumerable.Empty <IComponentRegistration>());
        }