/// <summary> /// The initialize. /// </summary> public void LoadLiveData(IWorkflowsQueryService client) { GetAllActivityLibrariesReplyDC reply; // gets the version for an ActivityAssemblyItem, or an empty string if it is null Func<ActivityAssemblyItem, string> getVersion = item => null == item.Version ? string.Empty : item.Version.ToString(); // checks to see if an ActivityAssemblyItem is already in the ActivityAssemblyItemCollection Func<ActivityLibraryDC, bool> isAlreadyInCollection = activityLibrary => ActivityAssemblyItemCollection .Any(activityAssemblyItem => activityAssemblyItem.Name == activityLibrary.Name && getVersion(activityAssemblyItem) == activityLibrary.VersionNumber); // Load from local caching Caching .ActivityAssemblyItems .ToList() .ForEach(activityAssemblyItem => ActivityAssemblyItemCollection.Add(activityAssemblyItem)); // Get the list of libraries that are on the server try { var request = new GetAllActivityLibrariesRequestDC { Incaller = Environment.UserName, IncallerVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString() }; reply = client.GetAllActivityLibraries(request); } 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); } // Require a pre-check since the list is not reliably instantiated // by the WCF service if ((null != reply) && (null != reply.List)) { // Each library which isn't already locally cached // should show up on the Select screen as a library // available on the server reply .List .Where(activityLibrary => !string.IsNullOrEmpty(activityLibrary.Name) && activityLibrary.HasExecutable && !isAlreadyInCollection(activityLibrary)) .ToList() .ForEach(activityLibrary => { var item = DataContractTranslator.ActivityLibraryDCToActivityAssemblyItem(activityLibrary); item.CachingStatus = CachingStatus.Server; ActivityAssemblyItemCollection.Add(item); }); } }
///<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 }