7

我正在尝试构建一个可移植的类库,它在可用时使用来自平台的实现。例如,Lazy<T>在 .NET 4.5、Windows Store Apps、Windows Phone 8 上可用,但在 Windows Phone 7、Silverlight 4 上不可用。当我的 PCL 加载到具有Lazy<T>实现的平台之一时,我想使用平台的实现。当它在平台上不可用时,我想使用我自己的实现。这似乎是可能的,因为微软 BCL 正在这样做,但我还没有弄清楚如何实现它。

我已经读过,通过使用TypeForwardedToAttribute,您可以重定向 PCL 以使用来自平台的实现。我不太确定如何配置我的 Visual Studio 项目以实现此结果。如果CoreLib是我的库,并且ShimLib包含我的Lazy<T>. 我在哪里添加 TypeForwardedToAttribute?该属性需要一个实际的类型引用typeof(System.Lazy<>),当 Windows Phone 7 以 PCL 为目标时,该引用不起作用。如果我删除 Windows Phone 7,那么我无法将 CoreLib 的引用添加到 ShimLib,因为 ShimLib 不支持 CoreLib 支持的所有平台。我该如何处理?

是的,我知道Lazy<T>它非常容易实现,但这只是一个例子,我的实际情况适用于更多不那么容易实现的类。

4

2 回答 2

8

Microsoft.Bcl 通过发送具有相同标识的两个程序集来做到这一点;一个是类型本身,一个是 forward 类型。在针对不支持 Lazy 的平台(包括包含这些平台之一的可移植库组合)时,您可以使用该类型引用该类型。并在使用 Lazy 定位平台时使用 type-forward 引用,这可以使用针对旧平台构建的库。

请注意,Microsoft.Bcl 有一点您没有的优势。我们发布的程序集与更高版本中已有的程序集具有相同的标识,这意味着当 Windows Phone 7应用程序在 Windows Phone 8 上运行时,它们将获得内置版本,而不是 shim 库中的版本。你无法模仿这一点,但这可能是你可以接受的情况。

于 2013-08-20T18:28:31.953 回答
5

这个问题和这篇文章很好地解释了类型转发的原理,这里不再赘述。然而,总而言之,这个想法是能够在A B重新编译的情况下重用一个库,即使它引用了一个正在被 library 替换的库C。为此,B必须修改 library 以便将引用转发到 library C,这正是 TypeForwardedTo 属性所做的。

这对你有什么帮助?好吧,您可以创建您ShimLib的所有项目都引用它,但使用条件编译和类型转发将其链接到框架库(如果它们存在)。幸运的是,有人已经 为您做到了:)

编辑回应马特的评论:你是对的,我忽略了 Theraot 并没有回退到最初的实现。而且我想如果不重新编译,这将很难实现。你能做的最好的可能就是遵循这个策略,即为不同的框架版本提供不同的构建配置。这样,您可以有条件地编译TypeForwardedToAttribute. 至少,这使您不必重复代码。如果您真的不想分发不同版本的代码,您可以实现一个引导程序,该引导程序确定框架版本并加载已使用此版本的构建配置编译的程序集版本

于 2013-08-19T06:37:09.927 回答