Esempio n. 1
0
 /// <summary>
 /// Create join point from export.
 /// </summary>
 /// <param name="instance">Instance where is export defined.</param>
 /// <param name="export">Export which join point is created.</param>
 internal JoinPoint(ComponentRef instance, Export export)
 {
     Point        = export;
     Contract     = export.Contract;
     ContractType = export.ExportType;
     Instance     = instance;
 }
Esempio n. 2
0
        private bool noInitializedCandidatesError(ComponentRef component, Import import, IEnumerable <ComponentRef> candidatesInProgress)
        {
            var importPoint = component.GetPoint(import);

            string error = "Can't satisfy import";

            if (candidatesInProgress.Any())
            {
                error += ", there are circular dependencies in prerequisity imports";

                foreach (var candidate in candidatesInProgress)
                {
                    makeErrorJoins(importPoint, candidate, "Can't get export because of unsatisfied prerequisities");
                }
            }
            else
            {
                error = noMatchingExportError(importPoint, error);
            }

            //set error to import
            setError(importPoint, error);


            if (import.IsPrerequisity)
            {
                setWarning(component.ExportPoints, "Because of unsatisfied prerequisity import, exports cannot be provided");
            }

            return(false);
        }
Esempio n. 3
0
        /// <summary>
        /// Can be satisfied only after Prerequisities imports has been satisfied
        /// </summary>
        /// <param name="inst"></param>
        /// <returns></returns>
        private bool satisfyNormImports(ComponentRef inst)
        {
            if (!inst.HasSatisfiedPreImports)
            {
                throw new NotSupportedException("InternalError:Cant satisfy imports before prerequisities are satisfied");
            }

            foreach (var import in inst.Imports)
            {
                if (import.IsPrerequisity)
                {
                    //satisfy only normal imports, because prerequisities has to be satisfied now
                    continue;
                }

                if (!satisfyImport(inst, import))
                {
                    //composition failed
                    return(false);
                }
            }

            inst.IsSatisfied = true;
            return(true);
        }
Esempio n. 4
0
        private bool satisfyFromCandidates(ComponentRef component, Import import, IEnumerable <ComponentRef> candidates)
        {
            var importPoint = component.GetPoint(import);

            foreach (var candidate in candidates)
            {
                if (!satisfyPreImports(candidate))
                {
                    setError(importPoint, "Cannot satisfy import, because depending component cannot be instantiated");
                    makeErrorJoins(importPoint, candidate, "This export cannot be provided before prerequisity imports are satisfied");

                    //satisfy all needed requirments
                    return(false);
                }

                if (!satisfyImport(component, import, candidate))
                {
                    //errors were set
                    return(false);
                }
            }

            if (!import.IsPrerequisity)
            {
                // else it will be set via importing constructor
                setImport(importPoint);
            }

            return(true);
        }
Esempio n. 5
0
        /// <summary>
        /// Satisfy given import. Found exports are added int storage
        /// </summary>
        /// <param name="component"></param>
        /// <param name="import"></param>
        /// <returns></returns>
        bool satisfyImport(ComponentRef component, Import import)
        {
            if (import.IsPrerequisity && component.IsConstructed)
            {
                //instance is already constructed - dont need satisfy via importing constructor
                return(true);
            }

            var candidates = getExportCandidates(import);
            //determine that import has any candidates
            //(even those, that cannot be used for import because of missing initialization)

            //filter candidates that are initialized now (circular dependency)
            var initializedCandidates    = candidates.Except(_currentPrereqInstances);
            var candidatesInProgress     = candidates.Intersect(_currentPrereqInstances);
            var hasInitializedCandidates = initializedCandidates.Any();

            if (!hasInitializedCandidates && !import.AllowDefault)
            {
                return(noInitializedCandidatesError(component, import, candidatesInProgress));
            }

            if (initializedCandidates.Count() > 1 && !import.AllowMany)
            {
                return(tooManyCandidatesError(component, import, initializedCandidates));
            }

            return(satisfyFromCandidates(component, import, initializedCandidates));
        }
Esempio n. 6
0
        /// <summary>
        /// Prerequisity imports has to be satisfied before component construction
        /// </summary>
        /// <param name="inst"></param>
        /// <returns></returns>
        private bool satisfyPreImports(ComponentRef inst)
        {
            if (inst.IsConstructed)
            {
                return(true);
            }

            if (inst.ComposingFailed)
            {
                //has been already proceeded
                return(false);
            }

            if (_currentPrereqInstances.Contains(inst))
            {
                //circular dependency
                return(false);
            }

            var  preImports = new List <ComponentRef>();
            bool satisfied  = true;

            _currentPrereqInstances.Add(inst); //avoid dependency cycling

            foreach (var import in inst.Imports)
            {
                if (!import.IsPrerequisity)
                {
                    //satisfy only prerequisities
                    continue;
                }

                if (satisfyImport(inst, import))
                {
                    //import was satisfied
                    continue;
                }

                satisfied = false;
                break;
            }

            _currentPrereqInstances.Remove(inst);

            if (!satisfied)
            {
                return(false);
            }

            if (!constructInstance(inst))
            {
                return(false);
            }

            inst.HasSatisfiedPreImports = true;
            return(true);
        }
Esempio n. 7
0
        private bool tooManyCandidatesError(ComponentRef component, Import import, IEnumerable <ComponentRef> candidates)
        {
            var importPoint = component.GetPoint(import);

            setError(importPoint, "There are more than one matching component for export satisfiyng");
            foreach (var expProvider in candidates)
            {
                makeErrorJoins(importPoint, expProvider, "Matching export in ambiguous component");
            }
            return(false);
        }
Esempio n. 8
0
        /// <summary>
        /// enqueue call importing/default constructor on instance
        /// </summary>
        /// <param name="inst"></param>
        private bool constructInstance(ComponentRef inst)
        {
            if (!inst.HasImportingConstructor)
            {
                setError(inst.ExportPoints, "Cannot provide exports because of missing importing or parameter less constructor");
                setError(inst.ImportPoints, "Cannot set imports, because of missing importing or parameter less constructor");
                _failed = true;
                return(false);
            }

            callImportingConstructor(inst);
            return(true);
        }
Esempio n. 9
0
        /// <summary>
        /// Add component which will be available at given component reference.
        /// </summary>
        /// <param name="component">The component.</param>
        /// <param name="componentRef">The component reference.</param>
        private void addInputComponent(Instance component, ComponentRef componentRef)
        {
            var argumentIndex = _inputInstances.Count;

            _inputInstances.Add(component);

            var storage = string.Format("$arg_{0}", argumentIndex);

            emit((e) => e.AssignArgument(storage, component.Info, (uint)argumentIndex));

            _instanceStorages.Add(componentRef, storage);
            _componentRefs.Add(componentRef);
        }
Esempio n. 10
0
        private void callImportingConstructor(ComponentRef component)
        {
            var args = new List <InstanceRef>();

            foreach (var import in component.Imports)
            {
                if (import.Setter == null) //has to be satisfied via importing constructor
                {
                    var imp = component.GetPoint(import);
                    args.Add(createExport(imp));
                }
            }

            component.Construct(component.ComponentInfo.ImportingConstructor, args.ToArray());
        }
Esempio n. 11
0
        /// <summary>
        /// make error joins between matching exports (used for showing errors)
        /// </summary>
        /// <param name="imp"></param>
        /// <param name="exportProvider"></param>
        /// <param name="expWarning"></param>
        private void makeErrorJoins(JoinPoint imp, ComponentRef exportProvider, string expWarning)
        {
            var exps = new List <JoinPoint>();

            foreach (var exp in exportProvider.ExportPoints)
            {
                if (!match(imp.Point as Import, exp))
                {
                    continue;
                }
                exps.Add(exp);
            }

            makeErrorJoins(imp, exps, expWarning);
        }
Esempio n. 12
0
        /// <summary>
        /// Adds the constructed components to the context.
        /// </summary>
        /// <param name="components">The constructed components.</param>
        internal void AddConstructedComponents(IEnumerable <Instance> components)
        {
            if (components == null)
            {
                return;
            }

            foreach (var component in components)
            {
                var info         = _services.GetComponentInfo(component.Info);
                var componentRef = new ComponentRef(this, true, info, component);

                addInputComponent(component, componentRef);
            }
        }
Esempio n. 13
0
        /// <summary>
        /// Create join point from import.
        /// </summary>
        /// <param name="instance">Instance where is import defined.</param>
        /// <param name="import">Import which join point is created.</param>
        internal JoinPoint(ComponentRef instance, Import import)
        {
            IsPrerequesity = import.IsPrerequisity;
            Point          = import;
            Contract       = import.Contract;

            AllowDefault = import.AllowDefault;
            AllowMany    = import.AllowMany;

            var info = import.ImportTypeInfo;

            ContractType   = info.ImportType;
            ImportItemType = info.ItemType;

            Instance = instance;
        }
Esempio n. 14
0
        private bool satisfyComponent(ComponentRef inst)
        {
            if (inst.IsSatisfied)
            {
                //instance has already been satisfied
                return(true);
            }

            if (inst.ComposingFailed)
            {
                //instance has been proceeded, but failed
                return(false);
            }


            var satisfied = satisfyPreImports(inst) && satisfyNormImports(inst);

            return(satisfied);
        }
Esempio n. 15
0
        /// <summary>
        /// find exports which satisfies import from exportsProvider (exportsProvider has been instatiated and its exports has to match into import)
        /// found exports are added into storage
        ///
        /// provide type checking of join, on fail set errors and return false
        /// </summary>
        /// <param name="component"></param>
        /// <param name="import"></param>
        /// <param name="exportsProvider"></param>
        private bool satisfyImport(ComponentRef component, Import import, ComponentRef exportsProvider)
        {
            Debug.Assert(exportsProvider.IsConstructed, "candidate has to be constructed before providing exports");

            var importPoint = component.GetPoint(import);

            foreach (var exportPoint in exportsProvider.ExportPoints)
            {
                if (match(import, exportPoint))
                {
                    var join = new Join(importPoint, exportPoint);
                    _joins.Add(join);

                    if (!typeCheck(join))
                    {
                        return(false);
                    }
                    _storage.Add(importPoint, exportPoint);
                }
            }

            return(true);
        }