我正在为我的玩具项目创建一个新的次要版本。该项目在 NuGet 上发布,与 .NET 4.0 及更高版本兼容。我介绍的一些新功能需要 .NET 4.5(用户应该能够解析.NET 4.5IReadOnlyCollection<T>
中IReadOnlyList<T>
引入的两个接口),但我需要保持项目与 .NET 4.0 兼容,因为并非所有开发人员可以轻松迁移到最新的 .NET 框架。
所以我面临的问题是如何解决这个“前向兼容性”问题。我想过两种解决方案,但都不是很有吸引力,所以希望任何人都可以在这里给我一些想法或指导。
这是我想出的两个解决方案:
解决方案 1:使用#if
编译器指令并为每个 .NET 框架版本构建一个 DLL,并使用 NuGet 包发布这些版本并在项目站点下载。
这种方法的缺点是,当开发人员将他们的 Visual Studio 项目从 .NET 4.0 更新到 .NET 4.5 时,他们不会自动获得 .NET 4.5 版本(具有 .NET 4.5 的特定功能)。这违反了最小惊讶原则,并且当开发人员在几个月后尝试使用该功能时,他们会对为什么该功能不起作用感到茫然。
解决方案 2:使用单个 DLL 并即时发出类型,当它们存在于当前应用程序域中时,它们会实现这两个新接口。这允许向用户发送单个 DLL,并允许在开发人员在其项目中切换 .NET 框架版本时使用功能。这将使事情“正常工作”。这是我目前正在前进的方向。
由于我需要返回一个需要实现接口的类型,缺点是必须在运行时使用 Reflection.Emit、ModuleBuilder、TypeBuilder 等创建该类型。这是非常讨厌的shizzle。但除此之外,由于必须在新的(匿名)程序集中创建此类型,我必须将一些内部类型公开(需要继承的类型和需要实现的接口)。将这些内部类型公开会污染项目的 API,并且不允许我对这些类型进行更改。
我相信这些是我的选择,但我可能会遗漏一些明显的东西。所以我的问题是,我错过了一种可能性吗?有没有办法绕过解决方案 1 的问题,还是使用运行时类型发射的核心根会更好?