Skip to content

Commit aa877b2

Browse files
committed
reduce duplicate codes
1 parent ffcfeec commit aa877b2

File tree

2 files changed

+46
-135
lines changed

2 files changed

+46
-135
lines changed

src/Smdn.Reflection.ReverseGenerating.ListApi.Core/Smdn.Reflection.ReverseGenerating.ListApi/AssemblyLoader.cs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,14 @@
1212
namespace Smdn.Reflection.ReverseGenerating.ListApi;
1313

1414
public static partial class AssemblyLoader {
15+
private readonly record struct AssemblySource(
16+
#pragma warning disable SA1313
17+
string ComponentAssemblyPath,
18+
FileInfo? File = null,
19+
Stream? Stream = null
20+
#pragma warning restore SA1313
21+
);
22+
1523
#if NULL_STATE_STATIC_ANALYSIS_ATTRIBUTES
1624
[return: MaybeNull]
1725
#endif
@@ -25,7 +33,10 @@ public static TResult UsingAssembly<TArg, TResult>(
2533
)
2634
{
2735
return UsingAssemblyCore(
28-
assemblyFile,
36+
new(
37+
ComponentAssemblyPath: assemblyFile.FullName,
38+
File: assemblyFile
39+
),
2940
loadIntoReflectionOnlyContext,
3041
arg,
3142
actionWithLoadedAssembly,
@@ -48,8 +59,10 @@ public static TResult UsingAssembly<TArg, TResult>(
4859
)
4960
{
5061
return UsingAssemblyCore(
51-
assemblyStream,
52-
componentAssemblyPath ?? throw new ArgumentNullException(nameof(componentAssemblyPath)),
62+
new(
63+
ComponentAssemblyPath: componentAssemblyPath ?? throw new ArgumentNullException(nameof(componentAssemblyPath)),
64+
Stream: assemblyStream
65+
),
5366
loadIntoReflectionOnlyContext,
5467
arg,
5568
actionWithLoadedAssembly,

src/Smdn.Reflection.ReverseGenerating.ListApi.Core/Smdn.Reflection.ReverseGenerating.ListApi/AssemblyLoader.netcore.cs

Lines changed: 30 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ partial class AssemblyLoader {
2424
[return: MaybeNull]
2525
#endif
2626
private static TResult UsingAssemblyCore<TArg, TResult>(
27-
FileInfo assemblyFile,
27+
AssemblySource assemblySource,
2828
bool loadIntoReflectionOnlyContext,
2929
TArg arg,
3030
Func<Assembly, TArg, TResult> actionWithLoadedAssembly,
@@ -36,51 +36,15 @@ private static TResult UsingAssemblyCore<TArg, TResult>(
3636

3737
if (loadIntoReflectionOnlyContext) {
3838
return UsingReflectionOnlyAssembly(
39-
assemblyFile,
39+
assemblySource,
4040
arg,
4141
actionWithLoadedAssembly,
4242
logger
4343
);
4444
}
4545
else {
4646
return UsingAssembly(
47-
assemblyFile,
48-
arg,
49-
actionWithLoadedAssembly,
50-
out context,
51-
logger
52-
);
53-
}
54-
}
55-
56-
#if NULL_STATE_STATIC_ANALYSIS_ATTRIBUTES
57-
[return: MaybeNull]
58-
#endif
59-
private static TResult UsingAssemblyCore<TArg, TResult>(
60-
Stream assemblyStream,
61-
string componentAssemblyPath,
62-
bool loadIntoReflectionOnlyContext,
63-
TArg arg,
64-
Func<Assembly, TArg, TResult> actionWithLoadedAssembly,
65-
out WeakReference? context,
66-
ILogger? logger = null
67-
)
68-
{
69-
context = default;
70-
71-
if (loadIntoReflectionOnlyContext) {
72-
return UsingReflectionOnlyAssembly(
73-
assemblyStream,
74-
componentAssemblyPath,
75-
arg,
76-
actionWithLoadedAssembly,
77-
logger
78-
);
79-
}
80-
else {
81-
return UsingAssembly(
82-
assemblyStream,
83-
componentAssemblyPath,
47+
assemblySource,
8448
arg,
8549
actionWithLoadedAssembly,
8650
out context,
@@ -93,59 +57,32 @@ private static TResult UsingAssemblyCore<TArg, TResult>(
9357
[return: MaybeNull]
9458
#endif
9559
private static TResult UsingReflectionOnlyAssembly<TArg, TResult>(
96-
FileInfo assemblyFile,
60+
AssemblySource assemblySource,
9761
TArg arg,
9862
Func<Assembly, TArg, TResult> actionWithLoadedAssembly,
9963
ILogger? logger = null
10064
)
10165
{
10266
using var mlc = new MetadataLoadContext(
103-
new PathAssemblyDependencyResolver(assemblyFile.FullName)
67+
new PathAssemblyDependencyResolver(assemblySource.ComponentAssemblyPath)
10468
);
10569

106-
logger?.LogDebug("loading assembly into reflection-only context from file '{AssemblyFilePath}'", assemblyFile.FullName);
107-
108-
var assm = mlc.LoadFromAssemblyPath(assemblyFile.FullName);
109-
110-
if (assm is null) {
111-
logger?.LogCritical("failed to load assembly from file '{AssemblyFilePath}'", assemblyFile.FullName);
112-
113-
return default;
114-
}
115-
116-
var assemblyName = assm.FullName;
117-
var assemblyTypeFullName = assm.GetType().FullName;
118-
11970
logger?.LogDebug(
120-
"loaded assembly '{AssemblyName}' ({AssemblyTypeFullName})",
121-
assemblyName,
122-
assemblyTypeFullName
71+
"loading assembly into reflection-only context (ComponentAssemblyPath: '{ComponentAssemblyPath}')",
72+
assemblySource.ComponentAssemblyPath
12373
);
12474

125-
return actionWithLoadedAssembly(assm, arg);
126-
}
127-
128-
#if NULL_STATE_STATIC_ANALYSIS_ATTRIBUTES
129-
[return: MaybeNull]
130-
#endif
131-
private static TResult UsingReflectionOnlyAssembly<TArg, TResult>(
132-
Stream assemblyStream,
133-
string componentAssemblyPath,
134-
TArg arg,
135-
Func<Assembly, TArg, TResult> actionWithLoadedAssembly,
136-
ILogger? logger = null
137-
)
138-
{
139-
using var mlc = new MetadataLoadContext(
140-
new PathAssemblyDependencyResolver(componentAssemblyPath)
141-
);
142-
143-
logger?.LogDebug("loading assembly into reflection-only context from stream with component assembly path '{ComponentAssemblyPath}'", componentAssemblyPath);
144-
145-
var assm = mlc.LoadFromStream(assemblyStream);
75+
var assm = assemblySource.File is not null
76+
? mlc.LoadFromAssemblyPath(assemblySource.File.FullName)
77+
: assemblySource.Stream is not null
78+
? mlc.LoadFromStream(assemblySource.Stream)
79+
: throw new InvalidOperationException($"either {nameof(AssemblySource.File)} or {nameof(AssemblySource.Stream)} must be specified");
14680

14781
if (assm is null) {
148-
logger?.LogCritical("failed to load assembly from stream");
82+
logger?.LogCritical(
83+
"failed to load assembly into reflection-only context (ComponentAssemblyPath: '{ComponentAssemblyPath}')",
84+
assemblySource.ComponentAssemblyPath
85+
);
14986

15087
return default;
15188
}
@@ -154,7 +91,7 @@ private static TResult UsingReflectionOnlyAssembly<TArg, TResult>(
15491
var assemblyTypeFullName = assm.GetType().FullName;
15592

15693
logger?.LogDebug(
157-
"loaded assembly '{AssemblyName}' ({AssemblyTypeFullName})",
94+
"loaded reflection-only assembly '{AssemblyName}' ({AssemblyTypeFullName})",
15895
assemblyName,
15996
assemblyTypeFullName
16097
);
@@ -167,7 +104,7 @@ private static TResult UsingReflectionOnlyAssembly<TArg, TResult>(
167104
#endif
168105
[MethodImpl(MethodImplOptions.NoInlining)]
169106
private static TResult UsingAssembly<TArg, TResult>(
170-
FileInfo assemblyFile,
107+
AssemblySource assemblySource,
171108
TArg arg,
172109
Func<Assembly, TArg, TResult> actionWithLoadedAssembly,
173110
out WeakReference? context,
@@ -176,64 +113,25 @@ private static TResult UsingAssembly<TArg, TResult>(
176113
{
177114
context = null;
178115

179-
var alc = new UnloadableAssemblyLoadContext(assemblyFile.FullName, logger);
116+
var alc = new UnloadableAssemblyLoadContext(assemblySource.ComponentAssemblyPath, logger);
180117
var alcWeakReference = new WeakReference(alc);
181118

182-
logger?.LogDebug("loading assembly from file '{AssemblyFilePath}'", assemblyFile.FullName);
183-
184-
var assm = alc.LoadFromAssemblyPath(assemblyFile.FullName);
185-
186-
if (assm is null) {
187-
logger?.LogCritical("failed to load assembly from file '{AssemblyFilePath}'", assemblyFile.FullName);
188-
189-
return default;
190-
}
191-
192-
context = alcWeakReference;
193-
194-
var assemblyName = assm.FullName;
195-
var assemblyTypeFullName = assm.GetType().FullName;
196-
197119
logger?.LogDebug(
198-
"loaded assembly '{AssemblyName}' ({AssemblyTypeFullName})",
199-
assemblyName,
200-
assemblyTypeFullName
120+
"loading assembly (ComponentAssemblyPath: '{ComponentAssemblyPath}')",
121+
assemblySource.ComponentAssemblyPath
201122
);
202123

203-
try {
204-
return actionWithLoadedAssembly(assm, arg);
205-
}
206-
finally {
207-
alc.Unload();
208-
209-
logger?.LogDebug("unloaded assembly '{AssemblyName}'", assemblyName);
210-
}
211-
}
212-
213-
#if NULL_STATE_STATIC_ANALYSIS_ATTRIBUTES
214-
[return: MaybeNull]
215-
#endif
216-
[MethodImpl(MethodImplOptions.NoInlining)]
217-
private static TResult UsingAssembly<TArg, TResult>(
218-
Stream assemblyStream,
219-
string componentAssemblyPath,
220-
TArg arg,
221-
Func<Assembly, TArg, TResult> actionWithLoadedAssembly,
222-
out WeakReference? context,
223-
ILogger? logger = null
224-
)
225-
{
226-
context = null;
227-
228-
var alc = new UnloadableAssemblyLoadContext(componentAssemblyPath, logger);
229-
var alcWeakReference = new WeakReference(alc);
230-
231-
logger?.LogDebug("loading assembly from stream with component assembly path '{ComponentAssemblyPath}'", componentAssemblyPath);
232-
233-
var assm = alc.LoadFromStream(assemblyStream);
124+
var assm = assemblySource.File is not null
125+
? alc.LoadFromAssemblyPath(assemblySource.File.FullName)
126+
: assemblySource.Stream is not null
127+
? alc.LoadFromStream(assemblySource.Stream)
128+
: throw new InvalidOperationException($"either {nameof(AssemblySource.File)} or {nameof(AssemblySource.Stream)} must be specified");
234129

235130
if (assm is null) {
236-
logger?.LogCritical("failed to load assembly from stream");
131+
logger?.LogCritical(
132+
"failed to load assembly (ComponentAssemblyPath: '{ComponentAssemblyPath}')",
133+
assemblySource.ComponentAssemblyPath
134+
);
237135

238136
return default;
239137
}

0 commit comments

Comments
 (0)