Ejemplo n.º 1
0
        public static IEnumerable <Type> GetForKey(this RegisteredTypeContext ctx, object key = null)
        {
            if (key == null)
            {
                return(ctx.Where(t => !ctx.Keys.ContainsKey(t)));
            }

            return(ctx.Where(t => ctx.Keys.ContainsKey(t) && ReferenceEquals(ctx.Keys[t], key)));
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Resolves the constructor parameters.
        /// </summary>
        /// <param name="lifetimeScope">The lifetime scope.</param>
        /// <param name="ctx">The CTX.</param>
        /// <param name="constructorInfo">The constructor ctx.</param>
        /// <param name="arguments">The arguments.</param>
        /// <param name="additionalParameters"></param>
        /// <returns>
        /// True, if resolving constructor parameters succeed.
        /// </returns>
        /// <exception cref="System.ArgumentNullException">
        /// constructorInfo
        /// or
        /// arguments
        /// </exception>
        private bool ResolveConstructorParameters(LifetimeScope lifetimeScope, RegisteredTypeContext ctx, MethodBase constructorInfo, ICollection <object> arguments, Parameter[] additionalParameters)
        {
            if (constructorInfo == null)
            {
                throw new ArgumentNullException("constructorInfo");
            }

            if (arguments == null)
            {
                throw new ArgumentNullException("arguments");
            }

            if (additionalParameters == null)
            {
                additionalParameters = new Parameter[0];
            }

            arguments.Clear();
            var outputType = constructorInfo.DeclaringType;

            var parameters         = constructorInfo.GetParameters().OrderBy(x => x.Position);
            var declaredParameters =
                additionalParameters.Concat(ctx.Parameters.ContainsKey(outputType)
                                                ? ctx.Parameters[outputType]
                                                : Enumerable.Empty <Parameter>());

            try
            {
                foreach (var parameterInfo in parameters)
                {
                    var paramterResolved = false;

                    foreach (var parameterCtx in
                             declaredParameters.Where(parameterCtx => parameterCtx.IsApplicable(parameterInfo)))
                    {
                        arguments.Add(parameterCtx.GetValue(constructorInfo.DeclaringType));
                        paramterResolved = true;
                        break;
                    }

                    if (paramterResolved)
                    {
                        continue;
                    }

                    var parameterInstance = this.Resolve(lifetimeScope, parameterInfo.ParameterType, outputType);
                    arguments.Add(parameterInstance);
                }

                return(true);
            }
            catch (NotAssignableException)
            {
                arguments.Clear();
                return(false);
            }
        }
Ejemplo n.º 3
0
        private void ActivateInModules(RegisteredTypeContext ctx, Type target, object instance)
        {
            var moduleForType = ctx.Modules.ContainsKey(target) ? ctx.Modules[target] : null;

            foreach (var module in this.AllModules)
            {
                module.InstanceActivated(target, instance);
                if (moduleForType != null && moduleForType == module)
                {
                    module.RegisteredInstanceActivated(target, instance);
                }
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Builds this instance as IResolvable and check if type collection is correct.
        /// </summary>
        /// <returns>IResolvable instance</returns>
        public ILifetimeScope Build()
        {
            this.ModuleRegistration();

            var resolvable = new Container
            {
                TypeContainer   = new Dictionary <Type, RegisteredTypeContext>(),
                ResolveImplicit = this.ResolveImplicit,
                AllModules      = this.modules.ToList()
            };

            resolvable.RegisterResolver(cnt => new EnumerableResolver());
            resolvable.RegisterResolver(cnt => new LazyResolver());
            resolvable.RegisterResolver(cnt => new ContainerItselfResolver());

            if (this.ActivatorEngine == null)
            {
                resolvable.ActivationEngine =
                    data => Activator.CreateInstance(data.ResolvedType, data.ConstructorArguments.ToArray());
            }
            else
            {
                resolvable.ActivationEngine = this.ActivatorEngine;
            }

            foreach (var nullType in
                     this.typeContainer.Where(resolvableItem => resolvableItem.AsType == null).ToList())
            {
                foreach (var inType in nullType.InTypes)
                {
                    this.typeContainer.Add((new ItemRegistration(nullType.Origin, inType)
                    {
                        Scope = nullType.Scope
                    }).As(inType));
                }
                this.typeContainer.Remove(nullType);
            }

            foreach (
                var builderResolvableItems in
                this.typeContainer
                .Where(resolvableItem => resolvableItem.AsType != null)
                .GroupBy(resolvableItem => resolvableItem.AsType))
            {
                var notResolvable =
                    builderResolvableItems.SelectMany(item => item.InTypes.Where(t => t.IsInterface || t.IsAbstract))
                    .FirstOrDefault();

                if (notResolvable != null)
                {
                    throw new NotAssignableException(
                              notResolvable,
                              $"Type \"{notResolvable.FullName}\" is abstract or interface so cannot be created.");
                }

                var ctx =
                    new RegisteredTypeContext(resolvable,
                                              builderResolvableItems.Select(item => item.InTypes)
                                              .SelectMany(types => types)
                                              .ToList());


                foreach (var builderResolvableItem in builderResolvableItems)
                {
                    if (builderResolvableItem.OwnFactory != null)
                    {
                        ctx.OwnFactories = builderResolvableItem.InTypes.ToDictionary(type => type,
                                                                                      type =>
                                                                                      builderResolvableItem.OwnFactory);
                    }

                    foreach (var type in builderResolvableItem.InTypes)
                    {
                        if (builderResolvableItem.Key != null)
                        {
                            ctx.Keys.Add(type, builderResolvableItem.Key);
                        }

                        foreach (var parameter in builderResolvableItem.Parameters)
                        {
                            if (!ctx.Parameters.ContainsKey(type))
                            {
                                ctx.Parameters.Add(type, new HashSet <Parameter>(new[] { parameter }));
                            }
                            else
                            {
                                if (!ctx.Parameters[type].Add(parameter))
                                {
                                    throw new InvalidOperationException(
                                              "Cannot add parameter. The same already registered.");
                                }
                            }
                        }
                    }
                }

                foreach (var item in builderResolvableItems)
                {
                    foreach (var inType in item.InTypes)
                    {
                        if (item.Module != null)
                        {
                            ctx.Modules.Add(inType, item.Module);
                        }

                        // TODO - key exist
                        ctx.Scopes.Add(inType, item.Scope);
                    }
                }

                var pair = new KeyValuePair <Type, RegisteredTypeContext>(builderResolvableItems.Key, ctx);
                resolvable.TypeContainer.Add(pair);
            }

            CheckForCycles(resolvable);

            GC.Collect();

            return(resolvable);
        }
Ejemplo n.º 5
0
 internal Scope WrapScope(LifetimeScope lifetimeScope, RegisteredTypeContext ctx, Scope desiredScope)
 {
     return(new ModuleDecorator(desiredScope, ctx, this.AllModules));
 }
Ejemplo n.º 6
0
        /// <summary>
        /// Creates the instance recursive.
        /// </summary>
        /// <param name="scope">The scope.</param>
        /// <param name="ctx">The CTX.</param>
        /// <param name="target">The target.</param>
        /// <param name="requestingType">Type of the requesting.</param>
        /// <param name="additionalParameters">Additional parameters to use for resolving</param>
        /// <returns></returns>
        /// <exception cref="NotAssignableException"></exception>
        internal object CreateInstanceRecursive(LifetimeScope scope, RegisteredTypeContext ctx, Type target, Type resolvedType, Type requestingType = null, params Parameter[] additionalParameters)
        {
            if (ctx.OwnFactories.ContainsKey(target))
            {
                var inst =
                    ctx.OwnFactories[target](new ActivationContext
                {
                    ActivatedType        = target,
                    CurrentLifetimeScope = scope,
                    RequestingType       = requestingType
                });

                if (inst == null)
                {
                    throw new CannotResolveTypeException(target);
                }
                if (!resolvedType.IsAssignableFrom(inst.GetType()))
                {
                    throw new CannotResolveTypeException(target);
                }

                return(inst);
            }

            if (target == typeof(object))
            {
                throw new InvalidOperationException("Object type must have instance factory specified.");
            }

            LinkedList <object> constructorArguments = null;

            var             constructors = target.GetConstructors();
            ConstructorInfo ctor         = null;

            if (constructors.Any())
            {
                foreach (var constructorInfo in constructors)
                {
                    var parametersInsance = new LinkedList <object>();
                    if (!this.ResolveConstructorParameters(scope, ctx, constructorInfo, parametersInsance, additionalParameters))
                    {
                        continue;
                    }

                    constructorArguments = parametersInsance;
                    ctor = constructorInfo;
                    break;
                }
            }

            if (constructorArguments == null || ctor == null)
            {
                throw new NotAssignableException(target, $"There is no constructors in type \"{target.FullName}\"");
            }

            var instance =
                this.ActivationEngine(
                    new ObjectActivatorData
            {
                ResolvedType         = target,
                ConstructorInfo      = ctor,
                ConstructorArguments = constructorArguments
            });

            this.ActivateInModules(ctx, target, instance);

            scope.ScopeAllInstances.Add(instance);

            return(instance);
        }
Ejemplo n.º 7
0
 public ModuleDecorator(Scope scope, RegisteredTypeContext typeContext, IEnumerable <Module> allModules)
 {
     this.typeContext = typeContext;
     this.allModules  = allModules;
     this.scope       = scope;
 }
Ejemplo n.º 8
0
 /// <summary>
 /// Wraps the scope.
 /// </summary>
 /// <param name="lifetimeScope">The lifetime scope.</param>
 /// <param name="ctx">The CTX.</param>
 /// <param name="desiredScope">The desired scope.</param>
 /// <returns></returns>
 protected Scope WrapScope(LifetimeScope lifetimeScope, RegisteredTypeContext ctx, Scope desiredScope)
 {
     return(lifetimeScope.Container.WrapScope(lifetimeScope, ctx, desiredScope));
 }