我正在为 .NET Core Web API 应用程序工作。我的要求是在家庭控制器中显示存储库(Bitbucket)最新的本地 git 提交 ID 。有人可以帮我解决这个问题吗?
我正在开发一个大型 ASP.Net 5 Web 应用程序,我想实现自我更新功能。由于程序可以以不同的方式部署在许多不同的平台上(例如Windows服务,Linux上的systemd服务,Docker容器等......),实现自我更新机制的唯一可行的方法是编写一个主机进程可以加载和卸载主程序DLL及其依赖项。卸载很重要,因为主机程序(更新程序)必须能够在运行时覆盖服务器的 DLL 文件。
以下是我到目前为止所做的工作:我已将主 Web 应用程序的输出类型更改为 Library,并且制作了一个小型加载程序,该程序将该 DLL 及其依赖项加载到 中HostAssemblyLoadContext,然后调用原始Main()方法。服务器应用程序被编程为在启动后几秒钟正常关闭,因此该CreateHostBuilder(args).Build().Run()方法Main()可以返回。之后,我尝试调用HostAssemblyLoadContext.Unload(),但由于某种原因,加载上下文拒绝实际卸载。
这是我的 HostAssemblyLoadContext 实现:
public class HostAssemblyLoadContext : AssemblyLoadContext
{
private readonly AssemblyDependencyResolver _resolver;
public HostAssemblyLoadContext(string pluginPath) : base(isCollectible: true)
{
_resolver = new AssemblyDependencyResolver(pluginPath);
}
protected override Assembly? Load(AssemblyName name)
{
string? assemblyPath = _resolver.ResolveAssemblyToPath(name);
if (assemblyPath != null)
return LoadFromAssemblyPath(assemblyPath);
string filePath = $"{name.FullName.Split(',')[0]}.dll";
if(File.Exists(filePath))
return Assembly.LoadFrom(filePath);
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
我的加载器代码:
[MethodImpl(MethodImplOptions.NoInlining)]
private static …Run Code Online (Sandbox Code Playgroud) 我有一个 .NET 4.8 ASP.NET 应用程序,并且添加了 Nuget
Azure.Security.KeyVault.Secrets, 4.3.0.0.
Azure.Identity, .1.6.0.0.
Run Code Online (Sandbox Code Playgroud)
在我的构建脚本上,它将 dll 复制到我的 bin 文件夹中,但是当我调试使用它的代码时,它会抛出错误Could not load file or assembly Azure.Core, Version=1.23.0.0
我检查过,我已经有 1.24.0.0参考。我认为这适用于版本 1.24,因为它在参考 >= 1.23 上说

Pre-bind state information
LOG: DisplayName = Azure.Core, Version=1.23.0.0, Culture=neutral, PublicKeyToken=92742159e12e44c8
(Fully-specified)
LOG: Appbase = file:///C:/xxx/
LOG: Initial PrivatePath = C:\xxx\bin
Calling assembly : Azure.Security.KeyVault.Secrets, Version=4.3.0.0, Culture=neutral, PublicKeyToken=92742159e12e44c8.
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\xxx\web.config
LOG: Using host configuration file: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet.config
LOG: Using machine configuration …Run Code Online (Sandbox Code Playgroud) 我有一个 .Net Framework WPF 应用程序,目前正在迁移到 .Net6。启动时,它会检查可执行文件夹中的某些程序集,查找具有自定义程序集属性的程序集。然后,那些具有此功能的应用程序将被加载到当前的应用程序域中。(请注意,其中一些程序集可能已经位于应用程序域中,因为它们是正在运行的应用程序的解决方案中的项目)。
这是 4.x 代码:
private void LoadAssemblies(string folder)
{
AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve +=
(s, e) => Assembly.ReflectionOnlyLoad(e.Name);
var assemblyFiles = Directory.GetFiles(folder, "*.Client.dll");
foreach (var assemblyFile in assemblyFiles)
{
var reflectionOnlyAssembly = Assembly.ReflectionOnlyLoadFrom(assemblyFile);
if (ContainsCustomAttr(reflectionOnlyAssembly))
{
var assembly = Assembly.LoadFrom(assemblyFile);
ProcessAssembly(assembly);
}
}
}
Run Code Online (Sandbox Code Playgroud)
自定义程序集属性(此代码正在查找)具有一个字符串属性,其中包含该程序集中 XAML 资源文件的路径。该ProcessAssembly()方法将此资源文件添加到应用程序的合并字典中,如下所示:
var resourceUri = string.Format(
"pack://application:,,,/{0};component/{1}",
assembly.GetName().Name,
mimicAssemblyAttribute.DataTemplatePath);
var uri = new Uri(resourceUri, UriKind.RelativeOrAbsolute);
application.Resources.MergedDictionaries.Add(new ResourceDictionary { Source = uri });
Run Code Online (Sandbox Code Playgroud)
重申一下,所有这些都在 .Net 4.x 应用程序中正常工作。
另一方面,.Net6不支持仅反射加载,也不能创建第二个应用程序域来加载程序集。我重写了上面的代码,将正在检查的程序集加载到我所理解的临时的、可卸载的上下文中:
private void …Run Code Online (Sandbox Code Playgroud) 我想在程序集级别替换一个类,以便所有引用都调用新的实现。可以说我在整个项目中的程序集中使用了通用类,例如
System.Generic.Collections.List
我的项目也引用了其他依赖的程序集List。
现在假设我想使用我的版本“ ListWhereever this is called”。
var values = new List<int> { 1, 2, 3, 4, 5 }
Run Code Online (Sandbox Code Playgroud)
如何在程序集级别替换类,以便我不必更新代码中的任何引用,或者可以在单个位置完成它。
我记得有元数据伙伴类和类似的东西是否可以使用全局编译指示进行覆盖?我依稀记得使用这样的语法:System.Generic.Collections.List::MyAssembly.List
我想以一种duck-typed底层类不必继承原始类的方式替换它,但我应该以相同的方式公开所有方法
注意:我需要以全局方式解决这个问题,通过反射或配置的单个入口点。
我过去已经做过动态替换方法的事情,请参阅:Dynamically Append Code to a method .Net-Core
我收到以下错误
Could not load file or assembly 'file:///C:\Users\<project path>\bin\DotNetOpenAuth.dll'
or one of it's dependencies. Operation is not supported.
(Exception from HRESULT: 0x80131515)
Run Code Online (Sandbox Code Playgroud)
当我尝试将Controller添加到MVC3框架内的Controllers文件夹时,我得到了这个.
我最近才开始使用MVC3和DotNetOpenAuth,我一直在使用教程来尝试学习它,我正在复制的部分是:http://www.asp.net/mvc/tutorials/getting-started-与-ASPNET-MVC3/CS /添加-A-模型
我仍然可以运行该项目,一切正常,我根本无法添加控制器.
我在Windows 7上使用VS .NET 2010(64位).
如果有任何其他需要的信息,请告诉我,提前谢谢!
TFS发出以下警告:
C:\ Windows\Microsoft.NET\Framework64\v4.0.30319\Microsoft.Common.targets(1605):正在构建的项目的处理器体系结构"MSIL"与参考"C:"的处理器体系结构不匹配\ Windows\Microsoft.NET\Framework64\v4.0.30319\System.Data.dll","AMD64".这种不匹配可能会导致运行时故障.请考虑通过Configuration Manager更改项目的目标处理器体系结构,以便在项目和引用之间调整处理器体系结构,或者依赖于具有与项目的目标处理器体系结构相匹配的处理器体系结构的引用.
"Release"和"Debug"配置都设置为使用"Any CPU"作为活动解决方案平台.
我将System.Data.dll的副本放入TEMP文件夹,并通过PowerShell提取有关此程序集的信息:
function ScanAssembly($assemblyPath) {
[reflection.assemblyname]::GetAssemblyName($assemblyPath)
}
$assemblyPath = "C:\TEMP\System.Data.dll"
$assemblyInfo = ScanAssembly($assemblyPath);
$assemblyInfo | fl;
Run Code Online (Sandbox Code Playgroud)
我得到以下输出:
Name : System.Data
Version : 4.0.0.0
CultureInfo :
CultureName :
CodeBase : file:///C:/TEMP/System.Data.dll
EscapedCodeBase : file:///C:/TEMP/System.Data.dll
ProcessorArchitecture : Amd64
ContentType : Default
Flags : PublicKey
HashAlgorithm : SHA1
VersionCompatibility : SameMachine
KeyPair :
FullName : System.Data, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=...
Run Code Online (Sandbox Code Playgroud)
出于某种原因,此程序集的ProcessorArchitecture设置为Amd64.我很困惑为什么它被设置为Amd64,因为我在Intel处理器上运行64位操作系统.
这些警告不是显示停止者,但我很难理解为什么我们看到它们.如果我理解正确的话,配置被设置为任何CPU,当为Amd64编译其中一个程序集时,这意味着它将不再适用于任何CPU - 它只能在64位CPU上运行.为什么为Amd64构建System.Data.dll超出了我的范围.
谢谢.
我正在尝试使用MEF为asp.net webforms制作某种插件系统.
到目前为止,我已经找到了一个解决方案,主机网站将在其插件文件夹中搜索加载名为Module的其他网站.模块(插件)只是另一个网站项目,因此它的bin子文件夹中有自己的程序集.
您当然已经知道,ASP.NET应用程序不会在其bin文件夹之外加载dll .因此,如果我尝试访问模块页面(例如:plugins/MyModule/Page.aspx).我会收到一个错误,说服务器无法加载程序集MyModule.我可以将模块的程序集放在主bin文件夹中,一切都会正常工作,但我想将所有模块文件保存在同一个文件夹中.
所以我正在寻找一种在bin文件夹之外加载程序集的方法.我已经尝试搞乱web.config文件,但无法提供有效的解决方案.
然后我来到BuildManager类并编写了这段代码:
string pluginPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "plugins");
foreach (string f in Directory.GetDirectories(pluginPath))
{
string binPath = Path.Combine(f, "bin");
if (Directory.Exists(binPath))
{
foreach (String file in Directory.GetFiles(binPath, "*.dll"))
{
Assembly a = Assembly.LoadFrom(file);
BuildManager.AddReferencedAssembly(a);
}
}
}
Run Code Online (Sandbox Code Playgroud)
它在plugin文件夹中搜索包含bin文件夹的任何其他子文件夹,并使用BuildManager加载相应的程序集.要使此代码有效,我必须在global.aspx程序集的PreApplicationStartMethod中调用它.
现在当我导航到插件页面(插件/ MyModule/Page.aspx)时,它不会给我以前的错误,但页面是空白的.我检查了源代码,没有html,没有.我试图调试页面,但从未调用Page_Load方法.所以我想某种方式从来没有调用Page.aspx背后的代码.
编辑:
所以在搜索了一下之后我找到了一个解决方案:
当我加载模块程序集时,我将其引用存储在一个dictionnay中.然后在 …
您可以加载程序集和查询中的所有组件属性,包括AssemblyInformationalVersionAttribute,AssemblyVersionAttribute和AssemblyFileVersionAttribute。但是,仅使用该Assembly.ReflectionOnlyLoadFrom方法打开程序集进行反射时,仅列出信息版本和文件版本,而不列出AssemblyVersionAttribute。
为什么我也没有得到该属性?
正如ILSpy演示的那样,Mono Cecil可以阅读所有内容。但是对于我的特定工具而言,该库太大了。
在我们的应用程序(具有65个项目的解决方案)中,将在运行时分析所有引用的程序集是否存在Ninject模块(也应用了一些过滤)。这些模块稍后会加载到Ninject内核中,并且每个模块都声明该内核的绑定。
我们采用了一种加载程序,该加载程序以“仅反射”模式将引用的程序集加载到单独的程序集中。与Ninject可以从目录中加载程序集的方式的不同之处在于,该目录可以包含带有不应加载的模块的程序集。而且从一开始,并不是所有引用的程序集都已加载。
问题在于,加载程序(贷给Sacha Barber)无法加载带有
System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information
Run Code Online (Sandbox Code Playgroud)
并LoaderExceptions带有一个条目:
Method 'BeforeLoad' in type 'Lekis.AppBase.Core.BLLBaseCore' from assembly 'AppBaseCore, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.
Run Code Online (Sandbox Code Playgroud)
以下是一些“有趣”的事实:
BeforeLoad是虚拟的,并且是接口方法的实现AppBaseCore是.NET 3.5,并且3个程序集无法加载AppBaseCore是.NET 4和5程序集加载失败当我使用ILSpy和ILDAsm检查程序集时,它们没有任何错误(很明显)。
在这一点上,我真的迷路了,不知道如何解决这个问题。
任何帮助表示赞赏。
谢谢
.net-assembly ×10
c# ×6
.net ×5
.net-core ×2
appdomain ×2
asp.net ×2
reflection ×2
asp.net-core ×1
attributes ×1
git ×1
jit ×1
mef ×1
nuget ×1
plugins ×1
tfs ×1
webapi ×1
webforms ×1