private void ProduceContentAssets()

in src/Microsoft.NuGet.Build.Tasks/ResolveNuGetPackageAssets.cs [509:580]


        private void ProduceContentAssets(JObject lockFile)
        {
            string valueSpecificPreprocessedOutputDirectory = null;
            var preprocessorValues = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

            // If a preprocessor directory isn't set, then we won't have a place to generate.
            if (!string.IsNullOrEmpty(ContentPreprocessorOutputDirectory))
            {
                // Assemble the preprocessor values up-front
                var duplicatedPreprocessorKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
                foreach (var preprocessorValueItem in ContentPreprocessorValues ?? Enumerable.Empty<ITaskItem>())
                {
                    if (preprocessorValues.ContainsKey(preprocessorValueItem.ItemSpec))
                    {
                        duplicatedPreprocessorKeys.Add(preprocessorValueItem.ItemSpec);
                    }

                    preprocessorValues[preprocessorValueItem.ItemSpec] = preprocessorValueItem.GetMetadata("Value");
                }

                foreach (var duplicatedPreprocessorKey in duplicatedPreprocessorKeys)
                {
                    Log.LogWarningFromResources(nameof(Strings.DuplicatePreprocessorToken), duplicatedPreprocessorKey, preprocessorValues[duplicatedPreprocessorKey]);
                }

                valueSpecificPreprocessedOutputDirectory = Path.Combine(ContentPreprocessorOutputDirectory, BuildPreprocessedContentHash(preprocessorValues));
            }

            // For shared content, it does not depend upon the RID so we should ignore it
            var target = GetTargetOrAttemptFallback(lockFile, needsRuntimeIdentifier: false);

            foreach (var package in GetPackagesFromTarget(lockFile, target))
            {
                var contentFiles = package.TargetObject["contentFiles"] as JObject;
                if (contentFiles != null)
                {
                    // Is there an asset with our exact language? If so, we use that. Otherwise we'll simply collect "any" assets.
                    string codeLanguageToSelect;

                    if (string.IsNullOrEmpty(ProjectLanguage))
                    {
                        codeLanguageToSelect = "any";
                    }
                    else
                    {
                        string nuGetLanguageName = GetNuGetLanguageName(ProjectLanguage);
                        if (contentFiles.Properties().Any(a => (string)a.Value["codeLanguage"] == nuGetLanguageName))
                        {
                            codeLanguageToSelect = nuGetLanguageName;
                        }
                        else
                        {
                            codeLanguageToSelect = "any";
                        }
                    }

                    foreach (var contentFile in contentFiles.Properties())
                    {
                        // Ignore magic _._ placeholder files. We couldn't ignore them during the project language
                        // selection, since you could imagine somebody might have a package that puts assets under
                        // "any" but then uses _._ to opt some languages out of it
                        if (Path.GetFileName(contentFile.Name) != "_._")
                        {
                            if ((string)contentFile.Value["codeLanguage"] == codeLanguageToSelect)
                            {
                                ProduceContentAsset(package, contentFile, preprocessorValues, valueSpecificPreprocessedOutputDirectory);
                            }
                        }
                    }
                }
            }
        }