Skip to content

Commit 1c9e9ff

Browse files
committed
Stop loading assemblies in ComponentCatalog.
Write the AssemblyName into the model, and use it to register the assembly during model load.
1 parent 350f77f commit 1c9e9ff

File tree

10 files changed

+292
-273
lines changed

10 files changed

+292
-273
lines changed

src/Common/AssemblyLoadingUtils.cs

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using Microsoft.ML.Runtime.Internal.Utilities;
6+
using System;
7+
using System.IO;
8+
using System.IO.Compression;
9+
using System.Reflection;
10+
11+
namespace Microsoft.ML.Runtime
12+
{
13+
internal static class AssemblyLoadingUtils
14+
{
15+
/// <summary>
16+
/// Make sure the given assemblies are loaded and that their loadable classes have been catalogued.
17+
/// </summary>
18+
public static void LoadAndRegister(string[] assemblies)
19+
{
20+
if (Utils.Size(assemblies) > 0)
21+
{
22+
foreach (string path in assemblies)
23+
{
24+
Exception ex = null;
25+
try
26+
{
27+
// REVIEW: Will LoadFrom ever return null?
28+
Contracts.CheckNonEmpty(path, nameof(path));
29+
var assem = LoadAssembly(path);
30+
if (assem != null)
31+
continue;
32+
}
33+
catch (Exception e)
34+
{
35+
ex = e;
36+
}
37+
38+
// If it is a zip file, load it that way.
39+
ZipArchive zip;
40+
try
41+
{
42+
zip = ZipFile.OpenRead(path);
43+
}
44+
catch (Exception e)
45+
{
46+
// Couldn't load as an assembly and not a zip, so warn the user.
47+
ex = ex ?? e;
48+
Console.Error.WriteLine("Warning: Could not load '{0}': {1}", path, ex.Message);
49+
continue;
50+
}
51+
52+
string dir;
53+
try
54+
{
55+
dir = CreateTempDirectory();
56+
}
57+
catch (Exception e)
58+
{
59+
throw Contracts.ExceptIO(e, "Creating temp directory for extra assembly zip extraction failed: '{0}'", path);
60+
}
61+
62+
try
63+
{
64+
zip.ExtractToDirectory(dir);
65+
}
66+
catch (Exception e)
67+
{
68+
throw Contracts.ExceptIO(e, "Extracting extra assembly zip failed: '{0}'", path);
69+
}
70+
71+
LoadAssembliesInDir(dir);
72+
}
73+
}
74+
}
75+
76+
private static string CreateTempDirectory()
77+
{
78+
string dir = GetTempPath();
79+
Directory.CreateDirectory(dir);
80+
return dir;
81+
}
82+
83+
private static string GetTempPath()
84+
{
85+
Guid guid = Guid.NewGuid();
86+
return Path.GetFullPath(Path.Combine(Path.GetTempPath(), "MLNET_" + guid.ToString()));
87+
}
88+
89+
private static void LoadAssembliesInDir(string dir)
90+
{
91+
if (!Directory.Exists(dir))
92+
return;
93+
94+
// Load all dlls in the given directory.
95+
var paths = Directory.EnumerateFiles(dir, "*.dll");
96+
foreach (string path in paths)
97+
{
98+
LoadAssembly(path);
99+
}
100+
}
101+
102+
/// <summary>
103+
/// Given an assembly path, load the assembly and register it with the ComponentCatalog.
104+
/// </summary>
105+
private static Assembly LoadAssembly(string path)
106+
{
107+
try
108+
{
109+
var assembly = Assembly.LoadFrom(path);
110+
ComponentCatalog.RegisterAssembly(assembly);
111+
return assembly;
112+
}
113+
catch (Exception)
114+
{
115+
return null;
116+
}
117+
}
118+
}
119+
}

0 commit comments

Comments
 (0)