Пример #1
0
        ///<summary>
        /// Compute ActivityAssemblyItem dependencies
        /// </summary>
        /// <param name="client"></param>
        /// <param name="assemblies"></param>
        /// <returns></returns>
        public static List<ActivityAssemblyItem> ComputeDependencies(IWorkflowsQueryService client, List<ActivityAssemblyItem> assemblies)
        {
            List<ActivityLibraryDC> assembliesOnServer;
            var dependencies = new MultiMap<int, int>();
            var neededIDs = new HashSet<int>();

            try
            {
                assembliesOnServer = client.GetAllActivityLibraries(new GetAllActivityLibrariesRequestDC().SetIncaller()).List;
            }
            catch (FaultException<ServiceFault> ex)
            {
                throw new CommunicationException(ex.Detail.ErrorMessage);
            }
            catch (FaultException<ValidationFault> ex)
            {
                throw new BusinessValidationException(ex.Detail.ErrorMessage);
            }
            catch (Exception ex)
            {
                throw new CommunicationException(ex.Message);
            }

            // get dependencies for each assembly
            foreach (var assembly in assemblies)
            {
                var dependenciesByID = client.StoreActivityLibraryDependenciesTreeGet(DataContractTranslator.ActivityAssemblyItemToStoreActivityLibrariesDependenciesDC(assembly));
                // for some reason, QueryService sends back list of lists instead of flattened list
                foreach (var dependencyContainer in dependenciesByID)
                {
                    foreach (var dependency in dependencyContainer.StoreDependenciesDependentActiveLibraryList)
                    {
                        // If A needs B, then A is the "parent" according to the data contract
                        var needs = dependency.activityLibraryParentId;
                        var needed = dependency.activityLibraryDependentId;
                        dependencies.AddValue(needs, needed);
                        neededIDs.Add(needed);
                    }
                }
            }

            var lookupById = new Dictionary<int, AssemblyName>();
            foreach (var serverAssembly in assembliesOnServer)
            {
                // determine the version number (can be nullable)
                Version serverAssemblyVersion = Version.TryParse(serverAssembly.VersionNumber, out serverAssemblyVersion) ? serverAssemblyVersion : null;

                // Don't use assembliesOnServer.ToDictionary() because test code can have key conflicts, e.g. all Id = 0 for some tests
                // that don't care about dependencies.
                lookupById[serverAssembly.Id] = new AssemblyName { Name = serverAssembly.Name, Version = serverAssemblyVersion };
            }

            var assembliesAndDependencies = new List<ActivityAssemblyItem>(
                from dbAsm in assembliesOnServer
                where neededIDs.Contains(dbAsm.Id)
                let cached = ActivityAssemblyItems.FirstOrDefault(
                         cached => string.Equals(cached.Name, dbAsm.Name) && string.Equals(cached.Version, dbAsm.VersionNumber)
                       )
                // prefer cached version over DB version to prevent re-download
                select cached ?? DataContractTranslator.ActivityLibraryDCToActivityAssemblyItem(dbAsm, from depId in dependencies.GetValues(dbAsm.Id).Distinct() let dependency = lookupById[depId] orderby dependency.Name, dependency.Version select dependency)
                );

            return assembliesAndDependencies; // pull it out into a separate variable for debuggability, vs. returning immediately
        }