【发布时间】:2020-11-18 19:08:23
【问题描述】:
背景 你好!我们的 .NET 5 Web 应用程序遵循“插件”架构。我们在整个网站上都有不同的模块,它们的独特性足以保证他们在我们的解决方案中拥有自己的项目。在应用程序启动时,我们的“主”应用程序会加载已编译的 DLL。目前,我们正在将我们的应用程序迁移到云端并转向微服务架构。最终,我们尝试将编译后的 DLL 存储在 AWS S3 中,在应用程序启动时下载并加载它们。
方法 我们能够毫无问题地从 S3 获取 DLL。据我们所知,有 3 种可能的方式来加载 DLL。来自 S3 的对象流被命名为“dll”。
(首选):
var assm = System.Runtime.Loader.AssemblyLoadContext.Default.LoadFromStream(dll);
mvcBuilder.AddApplicationPart(assm);
(不太好,但还不错):
using (var memoryStream = new MemoryStream())
{
dll.CopyTo(memoryStream);
var b = memoryStream.ToArray();
var assm = Assembly.Load(b);
mvcBuilder.AddApplicationPart(assm);
}
(最不喜欢的):
using (var fileStream = new FileStream(Environment.CurrentDirectory + "/tmp/Anon.dll", FileMode.Create,FileAccess.Write))
{
dll.CopyTo(fileStream);
var assm = Assembly.LoadFile(name);
mvcBuilder.AddApplicationPart(assm);
}
错误/意外行为 问题是最有利的方法 1 和 2 不起作用。应用程序返回详细的错误消息(堆栈跟踪位于下方)。如果我们使用与 S3 完全相同的 DLL 并将其加载到临时位置,则 DLL 会按预期加载。还值得一提的是,如果 DLL 已经作为文件存储在本地,转换为流并尝试加载 - 我们会收到相同的错误。我们做错了什么吗?是否存在我们不知道的限制?
ArgumentException: Empty path name is not legal. (Parameter 'path')
System.IO.FileStream..ctor(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options)
Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation.RazorReferenceManager.CreateMetadataReference(string path)
System.Linq.Enumerable+SelectListIterator<TSource, TResult>.ToList()
System.Linq.Enumerable.ToList<TSource>(IEnumerable<TSource> source)
Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation.RazorReferenceManager.GetCompilationReferences()
System.Threading.LazyInitializer.EnsureInitializedCore<T>(ref T target, ref bool initialized, ref object syncLock, Func<T> valueFactory)
System.Threading.LazyInitializer.EnsureInitialized<T>(ref T target, ref bool initialized, ref object syncLock, Func<T> valueFactory)
Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation.RazorReferenceManager.get_CompilationReferences()
Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation.LazyMetadataReferenceFeature.get_References()
Microsoft.CodeAnalysis.Razor.CompilationTagHelperFeature.GetDescriptors()
Microsoft.AspNetCore.Razor.Language.DefaultRazorTagHelperBinderPhase.ExecuteCore(RazorCodeDocument codeDocument)
Microsoft.AspNetCore.Razor.Language.RazorEnginePhaseBase.Execute(RazorCodeDocument codeDocument)
Microsoft.AspNetCore.Razor.Language.DefaultRazorEngine.Process(RazorCodeDocument document)
Microsoft.AspNetCore.Razor.Language.DefaultRazorProjectEngine.ProcessCore(RazorCodeDocument codeDocument)
Microsoft.AspNetCore.Razor.Language.RazorProjectEngine.Process(RazorProjectItem projectItem)
Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation.RuntimeViewCompiler.CompileAndEmit(string relativePath)
Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation.RuntimeViewCompiler.OnCacheMiss(string normalizedPath)
Microsoft.AspNetCore.Mvc.Razor.Compilation.DefaultRazorPageFactoryProvider.CreateFactory(string relativePath)
Microsoft.AspNetCore.Mvc.Razor.RazorViewEngine.CreateCacheResult(HashSet<IChangeToken> expirationTokens, string relativePath, bool isMainPage)
Microsoft.AspNetCore.Mvc.Razor.RazorViewEngine.OnCacheMiss(ViewLocationExpanderContext expanderContext, ViewLocationCacheKey cacheKey)
Microsoft.AspNetCore.Mvc.Razor.RazorViewEngine.LocatePageFromViewLocations(ActionContext actionContext, string pageName, bool isMainPage)
Microsoft.AspNetCore.Mvc.Razor.RazorViewEngine.FindView(ActionContext context, string viewName, bool isMainPage)
Microsoft.AspNetCore.Mvc.ViewEngines.CompositeViewEngine.FindView(ActionContext context, string viewName, bool isMainPage)
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewResultExecutor.FindView(ActionContext actionContext, ViewResult viewResult)
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewResultExecutor.ExecuteAsync(ActionContext context, ViewResult result)
Microsoft.AspNetCore.Mvc.ViewResult.ExecuteResultAsync(ActionContext context)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResultFilterAsync>g__Awaited|29_0<TFilter, TFilterAsync>(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext<TFilter, TFilterAsync>(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
感谢您的宝贵时间!
【问题讨论】:
-
这是known issue。
-
@JeroenMostert 这有助于解决我们的问题。非常感谢!
标签: c# .net-core .net-assembly