Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adjusted assembly-loading to be a bit more robust for .NETFramework-b… #367

Merged
merged 1 commit into from
Feb 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 26 additions & 13 deletions src/ExtendedXmlSerializer/ReflectionModel/AssemblyLoader.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
using System.Collections.Immutable;
using System;
using System.Collections.Immutable;
using System.IO;
using System.Reflection;

namespace ExtendedXmlSerializer.ReflectionModel
{
sealed class AssemblyLoader : IAssemblyLoader
{
readonly ImmutableArray<Assembly> _loaded;
public static AssemblyLoader Default { get; } = new AssemblyLoader();

AssemblyLoader() : this(AssemblyProvider.Default.Get()
.ToImmutableArray()) {}
AssemblyLoader() : this(AssemblyPath.Default.Get, AssemblyProvider.Default.Get().ToImmutableArray()) {}

AssemblyLoader(ImmutableArray<Assembly> loaded) => _loaded = loaded;
AssemblyLoader(Func<string, string> path, ImmutableArray<Assembly> loaded)
{
_path = path;
_loaded = loaded;
}

readonly Func<string, string> _path;
readonly ImmutableArray<Assembly> _loaded;

public Assembly Get(string parameter)
{
Expand All @@ -22,18 +28,25 @@ public Assembly Get(string parameter)
}
catch (FileNotFoundException)
{
var length = _loaded.Length;
for (var i = 0; i < length; i++)
try
{
var assembly = _loaded[i];
if (assembly.GetName()
.Name == parameter)
return Assembly.LoadFile(_path(parameter));
}
catch
{
var length = _loaded.Length;
for (var i = 0; i < length; i++)
{
return assembly;
var assembly = _loaded[i];
if (assembly.GetName()
.Name == parameter)
{
return assembly;
}
}
}

throw;
throw;
}
}
}
}
Expand Down
63 changes: 63 additions & 0 deletions src/ExtendedXmlSerializer/ReflectionModel/AssemblyPath.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
using ExtendedXmlSerializer.Core.Sources;
using System;
using System.Runtime.InteropServices;

namespace ExtendedXmlSerializer.ReflectionModel
{
/// <summary>
/// Attribution: https://stackoverflow.com/a/6131116/10340424
/// </summary>
sealed class AssemblyPath : IParameterizedSource<string, string>
{
public static AssemblyPath Default { get; } = new AssemblyPath();

AssemblyPath() {}

public string Get(string parameter)
{
if (parameter == null)
{
throw new ArgumentNullException(nameof(parameter));
}

var finalName = parameter;
var aInfo = new AssemblyInfo {cchBuf = 1024}; // should be fine...
aInfo.currentAssemblyPath = new string('\0', aInfo.cchBuf);

var hr = CreateAssemblyCache(out var ac, 0);
if (hr >= 0)
{
hr = ac.QueryAssemblyInfo(0, finalName, ref aInfo);
if (hr < 0)
{
return null;
}
}

return aInfo.currentAssemblyPath;
}

[DllImport("fusion.dll")]
static extern int CreateAssemblyCache(out IAssemblyCache ppAsmCache, int reserved);

[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("e707dcde-d1cd-11d2-bab9-00c04f8eceae")]
interface IAssemblyCache
{
void Reserved0();

[PreserveSig]
int QueryAssemblyInfo(int flags, [MarshalAs(UnmanagedType.LPWStr)] string assemblyName,
ref AssemblyInfo assemblyInfo);
}

[StructLayout(LayoutKind.Sequential)]
struct AssemblyInfo
{
readonly int cbAssemblyInfo;
readonly int assemblyFlags;
readonly long assemblySizeInKB;
[MarshalAs(UnmanagedType.LPWStr)] public string currentAssemblyPath;
public int cchBuf; // size of path buf.
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,6 @@
<PackageReference Include="xunit" Version="2.4.1" />
</ItemGroup>

<ItemGroup Condition=" '$(TargetFramework)' != 'netcoreapp2.1' ">
<Reference Include="WindowsBase" />
<Reference Include="System.Data">
<Private>True</Private>
</Reference>
</ItemGroup>

<ItemGroup Condition=" '$(TargetFramework)' == 'net452' ">
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
</ItemGroup>

<ItemGroup Condition=" '$(TargetFramework)' != 'net471' ">
<ProjectReference Include="..\..\src\ExtendedXmlSerializer\ExtendedXmlSerializer.csproj" />
</ItemGroup>
Expand Down
37 changes: 37 additions & 0 deletions test/ExtendedXmlSerializer.Tests.ReportedIssues/Issue366Tests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using ExtendedXmlSerializer.Configuration;
using ExtendedXmlSerializer.Tests.ReportedIssues.Support;
using FluentAssertions;
using System.Drawing;
using Xunit;

namespace ExtendedXmlSerializer.Tests.ReportedIssues
{
public sealed class Issue366Tests
{
[Fact]
void Verify()
{
var instance = new Model();
new ConfigurationContainer().Create()
.ForTesting()
.Cycle(instance)
.Should()
.BeEquivalentTo(instance);
}

public class Model
{
public Model()
{
NestedModel = new NestedModel();
}

public NestedModel NestedModel { get; set; }
}

public class NestedModel
{
public Size Size { get; set; }
}
}
}