为什么NuGet在NuGet包更新期间向库项目添加带有assemblyBinding的app.config?

为什么NuGet在NuGet包更新期间向库项目添加带有assemblyBinding的app.config?,nuget,Nuget,这些信息不是只有在可执行文件的项目中才需要吗 如何禁用此文件创建 NuGet 2.8 编辑 库项目在NuGet 2.7中是例外,在2.8中通过修复此问题改变了行为:通过提交:程序集绑定重定向在类库中与在可执行项目中一样有效 想想这个,;构建应用程序时,编译器如何知道要使用引用程序集的哪个版本(对于类库) 通常情况下,如果没有重定向,这将很好地工作,但是当您在一台具有GAC’ed版本的程序集的机器上绊倒时,您可能会遇到麻烦 我建议你阅读这本书,以便更好地理解它是什么,它的作用是什么 NuGet添加

这些信息不是只有在可执行文件的项目中才需要吗

如何禁用此文件创建

NuGet 2.8

编辑


库项目在NuGet 2.7中是例外,在2.8中通过修复此问题改变了行为:通过提交:

程序集绑定重定向在类库中与在可执行项目中一样有效

想想这个,;构建应用程序时,编译器如何知道要使用引用程序集的哪个版本(对于类库)

通常情况下,如果没有重定向,这将很好地工作,但是当您在一台具有GAC’ed版本的程序集的机器上绊倒时,您可能会遇到麻烦

我建议你阅读这本书,以便更好地理解它是什么,它的作用是什么

NuGet添加了带有重定向的app.config来帮助您,坦率地说,我不知道额外的app.config是否能让一切正常工作

从今天起,它将向所有项目添加重定向,但以下类型除外:

  • 巫师
  • JS
  • 内默尔
  • C++
  • 增效剂
  • Visual Studio
  • Windows应用商店应用程序
据我所知,这是无法关闭的。如果这是个问题,你可以


可以找到添加程序集绑定重定向的源代码。

我创建了一个小控制台应用程序,它检查app.config文件的所有日期,然后自动从.csproj和文件中删除它们。Todo:从tfs中删除。 也许这会有所帮助

class Program
{
    private static string RootFolder;
    private static string AppConfigName;
    private static bool AskConfirmation = true;
    static void Main(string[] args)
    {
        try
        {
            AppConfigName = "app.config";
            RootFolder = @"<Your project path>";
            ScanDir(RootFolder);
            Console.WriteLine();
            Console.WriteLine("DONE!");
            Console.WriteLine("Press ENTER to finish...");
            Console.ReadLine();

        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }

    private static void ScanDir(string directoryParent)
    {
        var dirs = Directory.GetDirectories(directoryParent);
        foreach (var dir in dirs)
        {
            var dirInfo = new DirectoryInfo(dir);
            if (dirInfo.Name == "bin" || dirInfo.Name == "obj" || dirInfo.Name == "debug" || dirInfo.Name == "tempPE" || dirInfo.Name == "java" || dirInfo.Name == "res") continue;
            var files = Directory.GetFiles(dir, "app.config");
            if (files.Length == 0)
            {
                ScanDir(dir);
                continue;
            }
            Process(dir);
            //ScanDir(dir);
        }
    }

    private static void Process(string dir)
    {
        var fi = new FileInfo(Path.Combine(dir, AppConfigName));
        if (fi.CreationTime.Date != DateTime.Now.Date) return;
        if (AskConfirmation)
        {
            Console.WriteLine("Scan " + dir.Replace(RootFolder, ""));
            Console.Write("Remove (y)es or (n)o ?");
            var key = Console.ReadKey();
            Console.WriteLine();
            if (key.Key.ToString() =="Y")
                // remove app.config
                RemoveAppConfig(dir, fi);
        }
        else
            RemoveAppConfig(dir, fi);
    }

    private static void RemoveAppConfig(string dir, FileInfo fi)
    {
        var csProjs = Directory.GetFiles(dir, "*.csproj");
        foreach (var csProj in csProjs)
        {
            var txt = File.ReadAllText(csProj);
            txt = Regex.Replace(txt,"<None Include=\"App.Config\" />", "",RegexOptions.IgnoreCase);
            File.Delete(csProj);
            File.WriteAllText(csProj, txt);
        }
        File.Delete(fi.FullName);
        // todo: undo in tfs
        Console.WriteLine("Deleted");
    }
}
类程序
{
私有静态字符串根文件夹;
私有静态字符串AppConfigName;
私有静态bool AskConfirmation=true;
静态void Main(字符串[]参数)
{
尝试
{
AppConfigName=“app.config”;
RootFolder=@;
ScanDir(根文件夹);
Console.WriteLine();
控制台。WriteLine(“完成!”);
Console.WriteLine(“按ENTER键完成…”);
Console.ReadLine();
}
捕获(例外情况除外)
{
控制台写入线(例如消息);
}
}
私有静态void ScanDir(字符串目录父级)
{
var dirs=Directory.GetDirectories(directorypent);
foreach(目录中的var dir)
{
var dirInfo=新目录信息(dir);
如果(dirInfo.Name==“bin”| dirInfo.Name==“obj”| dirInfo.Name==“debug”| dirInfo.Name==“tempPE”| dirInfo.Name==“java”| dirInfo.Name==“res”)继续;
var files=Directory.GetFiles(dir,“app.config”);
如果(files.Length==0)
{
斯堪的纳维亚(迪尔);
继续;
}
工艺(dir);
//斯堪的纳维亚(迪尔);
}
}
私有静态无效进程(字符串目录)
{
var fi=新文件信息(Path.Combine(dir,AppConfigName));
如果(fi.CreationTime.Date!=DateTime.Now.Date)返回;
如果(ASKC确认)
{
Console.WriteLine(“扫描”+dir.Replace(RootFolder)”);
控制台。写入(“删除(y)es或(n)o?”);
var key=Console.ReadKey();
Console.WriteLine();
if(key.key.ToString()=“Y”)
//删除app.config
RemoveAppConfig(目录,fi);
}
其他的
RemoveAppConfig(目录,fi);
}
私有静态void RemoveAppConfig(字符串目录、文件信息fi)
{
var csProjs=Directory.GetFiles(dir,*.csproj”);
foreach(csProjs中的var csProj)
{
var txt=File.ReadAllText(csProj);
txt=Regex.Replace(txt,“,”,RegexOptions.IgnoreCase);
文件删除(csProj);
writealText文件(csProj,txt);
}
File.Delete(fi.FullName);
//todo:在tfs中撤消
Console.WriteLine(“已删除”);
}
}

NuGet package manager将程序集绑定重定向添加到库项目的原因是,有些项目的输出类型是库,但有一些特殊的机制可以确保库的应用程序或web配置文件将在运行时应用。这与您可能熟悉的更典型的库用法相反,其中根本不使用库的配置文件

例如,Azure SDK 1.8+中的Azure Web和工作者角色项目将生成库,但当IIS将它们包装在exe中时,库的配置文件将设置为该exe的默认文件。这样,您就可以获得所有应用程序配置,而不必显式发布与包装可执行文件同名的特殊配置文件。现在,构建过程输出重命名的配置文件(例如app.config->myWebRoleLibrary.dll.config),一切正常

);加载测试程序集的app.config,而不是测试运行程序进程的app config

值得一提的是,你也可以,不管是不是图书馆。您必须确保配置文件最终位于正确的位置,但这是可能的。但这不太适用于绑定重定向,因为这些重定向通常仅由CLR中的程序集加载程序使用。我想你可以钩,但现在我们很好地在我们的道路上拙劣地重新发明车轮

所以,“在我的图书馆项目中有必要吗?”的答案可能是。如果您的库项目不是web或worker角色或测试项目,并且没有手动加载配置文件,则app.config可能是良性的,但不必要

至于禁用它,您只能在VisualStudio级别执行此操作。您可以在VS2019中找到该选项:工具->选项…->NuGet包管理器->常规->跳过应用绑定重定向

什么使用我的配置文件? 编译器(csc.exe) 编译器使用正在生成的程序集的配置文件有一个原因: