Esempio n. 1
0
        private ObjectBuildingInfo <TAddress> GetDependenciesInt(TAddress address)
        {
            if (address == null)
            {
                throw new ArgumentNullException(nameof(address));
            }

            // Check to see if we've been asked to build this before, if so, simply return
            ObjectBuildingInfo <TAddress> objectBuildingInfo = null;

            lock (this._objectBuildingInfo)
            {
                if (_objectBuildingInfo.TryGetValue(address, out objectBuildingInfo))
                {
                    return(objectBuildingInfo);
                }

                objectBuildingInfo            = new ObjectBuildingInfo <TAddress>(this, address);
                _objectBuildingInfo [address] = objectBuildingInfo;
            }

            // At this stage, we're now responsible for the population of this chap...
            if (this.ObjectBuilderProvider.TryGetObjectBuilder(address, out var objectBuilder))
            {
                try
                {
                    objectBuildingInfo.SetObjectBuilder(objectBuilder);

                    if (objectBuilder is ObjectBuilders.IObjectBuilderAsynchronousDependencies <TAddress> &&
                        ((ObjectBuilders.IObjectBuilderAsynchronousDependencies <TAddress>)objectBuilder).GetDependenciesAsynchronously(address))
                    {
                        // Create a task to do discovery and then to perform the
                        var job = new Tasks.ObjectBuilderGetDependenciesTask <TAddress>(this,
                                                                                        objectBuildingInfo,
                                                                                        address);

                        this.TaskRunner.RegisterTask(job);
                    }
                    else
                    {
                        var context      = new ObjectBuilders.ObjectBuilderGetDependenciesContext <TAddress>(this);
                        var dependencies = objectBuilder.GetDependencies(context, address);

                        if (dependencies != null && dependencies.RecursiveMode)
                        {
                            var dependencyTuples = new List <Tuple <ObjectBuilders.IDependency <TAddress>, IObjectBuildingInfo <TAddress> > >();
                            // Recursive mode
                            foreach (var dependency in dependencies.Dependencies)
                            {
                                var dependencyObjectBuildingInfo = this.BuildObject(dependency.Address);
                                var tuple = Tuple.Create(dependency, dependencyObjectBuildingInfo);
                                dependencyTuples.Add(tuple);
                            }

                            var callBackHandler = new ObjectBuilderRecursiveDependenciesCallBackHandler <TAddress>(
                                objectBuildingInfo,
                                dependencyTuples);

                            foreach (var tuple in dependencyTuples)
                            {
                                tuple.Item2.RegisterPostBuildCallBack(callBackHandler.PostDependencyBuildCallBack);
                            }
                        }
                        else
                        {
                            var requestedDependencies = new RequestedDependencies <TAddress>(
                                false,
                                dependencies == null ? null : dependencies.Dependencies);

                            objectBuildingInfo.SetRequestedDependencies(requestedDependencies);
                        }
                    }
                }
                catch (Exception ex)
                {
                    objectBuildingInfo.SetObjectFailed(ex);
                }
                return(objectBuildingInfo);
            }
            else
            {
                // This needs to be extended to ask for items from the child context...
                var parentContext = (ObjectContext <TAddress>) this.ParentContext;
                if (parentContext == null)
                {
                    objectBuildingInfo.SetNoBuilderFound();
                    return(objectBuildingInfo);
                }

                var parentContextObjectBuildingInfo = parentContext.GetDependencies(address);

                parentContextObjectBuildingInfo.RegisterPostDependenciesKnownCallBack((x) =>
                {
                    if (parentContextObjectBuildingInfo.ObjectBuildingState == ObjectBuildingStates.Failure)
                    {
                        objectBuildingInfo.SetObjectFailed(new Exception("Parent dependencies failed"));
                        return;
                    }

                    objectBuildingInfo.SetObjectBuilder(parentContextObjectBuildingInfo.ObjectBuilder);
                    objectBuildingInfo.SetRequestedDependencies(parentContextObjectBuildingInfo.RequestedDependencies);
                });
                return(objectBuildingInfo);
            }
        }
        private void RunGetAdditionalDependencies()
        {
            try
            {
                var dependencySet = new ObjectBuilders.BuiltDependencies <TAddress>();
                if (this.Dependencies.Any(tuple => tuple.Item2.ObjectBuildingState != ObjectBuildingStates.ObjectBuilt))
                {
                    this.ObjectBuildingInfo.SetObjectFailed(new InvalidOperationException("Dependency Failed"));
                    return;
                }

                foreach (var entry in this.Dependencies)
                {
                    dependencySet.AddDependency(entry.Item1.Name,
                                                entry.Item1.Address,
                                                entry.Item2.BuiltObject);
                }

                var context = new ObjectBuilders.ObjectBuilderGetAdditionalDependenciesContext <TAddress>(this.ObjectBuildingInfo.ObjectContext);

                var additionalDependencies = this.ObjectBuildingInfo.ObjectBuilder.GetAdditionalDependencies(context, this.ObjectBuildingInfo.Address, dependencySet);

                IEnumerable <ObjectBuilders.IDependency <TAddress> > combinedDependencies = this.Dependencies.Select(tuple => tuple.Item1);
                if (additionalDependencies != null)
                {
                    combinedDependencies = combinedDependencies.Concat(additionalDependencies.Dependencies);
                }

                if (additionalDependencies == null || !additionalDependencies.RecursiveMode)
                {
                    // Say that the dependencies are now know...
                    var requestedDependencies = new RequestedDependencies <TAddress>(
                        false,
                        combinedDependencies);

                    this.ObjectBuildingInfo.SetRequestedDependencies(requestedDependencies);
                }
                else if (additionalDependencies.RecursiveMode)
                {
                    var dependencyTuples = new List <Tuple <ObjectBuilders.IDependency <TAddress>, IObjectBuildingInfo <TAddress> > >();
                    // Recursive mode
                    foreach (var dependency in combinedDependencies)
                    {
                        var dependencyObjectBuildingInfo = this.ObjectBuildingInfo.ObjectContext.BuildObject(dependency.Address);
                        var tuple = Tuple.Create(dependency, dependencyObjectBuildingInfo);
                        dependencyTuples.Add(tuple);
                    }

                    var callBackHandler = new ObjectBuilderRecursiveDependenciesCallBackHandler <TAddress>(
                        this.ObjectBuildingInfo,
                        dependencyTuples);

                    foreach (var tuple in dependencyTuples)
                    {
                        tuple.Item2.RegisterPostBuildCallBack(callBackHandler.PostDependencyBuildCallBack);
                    }
                }
            }
            catch (Exception ex)
            {
                this.ObjectBuildingInfo.SetObjectFailed(ex);
            }
        }