Read original app.config and add to it

This commit is contained in:
Pavel Krymets 2015-12-10 08:58:18 -08:00
parent 1115fc22fa
commit 91acc03a13
2 changed files with 81 additions and 35 deletions

View file

@ -34,43 +34,77 @@ namespace Microsoft.DotNet.Tools.Compiler
private readonly SHA1 _sha1 = SHA1.Create();
public XDocument Generate(IEnumerable<LibraryExport> dependencies)
public XDocument Generate(IEnumerable<LibraryExport> dependencies, XDocument document)
{
var redirects = CollectRedirects(dependencies);
if (!redirects.Any())
{
// No redirects required
return null;
return document;
}
document = document ?? new XDocument();
var configuration = GetOrAddElement(document, ConfigurationElementName);
var runtime = GetOrAddElement(configuration, RuntimeElementName);
var assemblyBindings = GetOrAddElement(runtime, AssemblyBindingElementName);
foreach (var redirect in redirects)
{
AddDependentAssembly(redirect, assemblyBindings);
}
var document = new XDocument(
new XElement(ConfigurationElementName,
new XElement(RuntimeElementName,
new XElement(AssemblyBindingElementName,
redirects.Select(GetDependentAssembly)
)
)
)
);
return document;
}
private XElement GetDependentAssembly(AssemblyRedirect redirect)
private void AddDependentAssembly(AssemblyRedirect redirect, XElement assemblyBindings)
{
var culture = string.IsNullOrEmpty(redirect.From.Culture) ? "neutral" : redirect.From.Culture;
var dependencyElement = assemblyBindings.Elements(DependentAssemblyElementName)
.FirstOrDefault(element => IsSameAssembly(redirect, element));
return new XElement(DependentAssemblyElementName,
if (dependencyElement == null)
{
dependencyElement = new XElement(DependentAssemblyElementName,
new XElement(AssemblyIdentityElementName,
new XAttribute(NameAttributeName, redirect.From.Name),
new XAttribute(PublicKeyTokenAttributeName, redirect.From.PublicKeyToken),
new XAttribute(CultureAttributeName, culture)
),
new XElement(BindingRedirectElementName,
new XAttribute(OldVersionAttributeName, redirect.From.Version),
new XAttribute(NewVersionAttributeName, redirect.To.Version)
new XAttribute(CultureAttributeName, redirect.From.Culture)
)
);
assemblyBindings.Add(dependencyElement);
}
dependencyElement.Add(new XElement(BindingRedirectElementName,
new XAttribute(OldVersionAttributeName, redirect.From.Version),
new XAttribute(NewVersionAttributeName, redirect.To.Version)
));
}
private bool IsSameAssembly(AssemblyRedirect redirect, XElement dependentAssemblyElement)
{
var identity = dependentAssemblyElement.Element(AssemblyIdentityElementName);
if (identity == null)
{
return false;
}
return (string) identity.Attribute(NameAttributeName) == redirect.From.Name &&
(string) identity.Attribute(PublicKeyTokenAttributeName) == redirect.From.PublicKeyToken &&
(string) identity.Attribute(CultureAttributeName) == redirect.From.Culture;
}
public static XElement GetOrAddElement(XContainer parent, XName elementName)
{
XElement element;
if (parent.Element(elementName) != null)
{
element = parent.Element(elementName);
}
else
{
element = new XElement(elementName);
parent.Add(element);
}
return element;
}
private AssemblyRedirect[] CollectRedirects(IEnumerable<LibraryExport> dependencies)
@ -110,14 +144,11 @@ namespace Microsoft.DotNet.Tools.Compiler
var definition = metadataReader.GetAssemblyDefinition();
var publicKey = metadataReader.GetBlobBytes(definition.PublicKey);
var publicKeyToken = GetPublicKeyToken(publicKey);
var identity = new AssemblyIdentity(
metadataReader.GetString(definition.Name),
definition.Version,
metadataReader.GetString(definition.Culture),
publicKeyToken
GetPublicKeyToken(metadataReader.GetBlobBytes(definition.PublicKey))
);
var references = new List<AssemblyIdentity>(metadataReader.AssemblyReferences.Count);
@ -184,7 +215,7 @@ namespace Microsoft.DotNet.Tools.Compiler
{
Name = name;
Version = version;
Culture = culture;
Culture = string.IsNullOrEmpty(culture)? "neutral" : culture;
PublicKeyToken = publicKeyToken;
}

View file

@ -6,7 +6,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Xml.Linq;
using Microsoft.Dnx.Runtime.Common.CommandLine;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Cli.Compiler.Common;
@ -507,17 +507,32 @@ namespace Microsoft.DotNet.Tools.Compiler
private static void GenerateBindingRedirects(ProjectContext runtimeContext, string outputPath, LibraryExporter exporter)
{
var generator = new BindingRedirectGenerator();
var config = generator.Generate(exporter.GetAllExports());
var appConfigNames = new[] { "app.config", "App.config" };
XDocument baseAppConfig = null;
if (config != null)
foreach (var appConfigName in appConfigNames)
{
var baseAppConfigPath = Path.Combine(runtimeContext.ProjectDirectory, appConfigName);
if (File.Exists(baseAppConfigPath))
{
using (var fileStream = File.OpenRead(baseAppConfigPath))
{
baseAppConfig = XDocument.Load(fileStream);
break;
}
}
}
var generator = new BindingRedirectGenerator();
var appConfig = generator.Generate(exporter.GetAllExports(), baseAppConfig);
if (appConfig != null)
{
// TODO: Handle existing App.config file transformation
// We have something to generate
var path = Path.Combine(outputPath, runtimeContext.ProjectFile.Name + ".exe.config");
using (var stream = File.Create(path))
{
config.Save(stream);
appConfig.Save(stream);
}
}
}