Visual Studio 2012中的对象浏览器为Portable类库提供了两个不同的组件集:
当我创建可移植类库时,它使用.NET Portable Subset。什么是第二套,我该如何使用它?它包含MEF is not available in .NET Portable Subset。
答案 0 :(得分:32)
是的,这是令人困惑的,并且基本上是因为对象浏览器没有很好的方法(我们无法在没有重大重写的情况下在此版本中添加方法)来表示可移植子集。
为了帮助阐明这一点,请考虑以下图表:
圆圈表示各个平台的API表面区域(不按比例)。在便携式中,我们有效地暴露了重叠区域中存在的API。例如,当针对上述所有三个时,我们让您构建所有三个平台相交的表面区域(即正中心)。在针对Windows应用商店和.NET Framework进行定位时,我们允许您针对这两个平台相交的交叉点(即中心和右下角)进行构建。针对更多平台,您可以使用的可用表面积减少,目标更少的平台和您使用的表面积增加。如果您考虑一下,这是有道理的,您组合的平台越多,它们的共同点就越少。
这与您在对象浏览器中看到的内容有何关系?
在对象浏览器中,我们没有一种简单的方法来公开那些单独的交叉点(当你考虑平台数量+个别版本时,有很多!)。因此,我们所做的就是抓住便携式中所有可用的表面区域(即所有交叉点组合在一起),而不是暴露它。这意味着对象浏览器向您展示了我们认为在所有平台上“可移植”的所有API的组合。
这就是你看MEF的原因。当您定位.NET Framework和Silverlight时,MEF可用,但只要您将Phone或Windows Store添加到目标,就会丢失它,因为在这些平台上不支持它。
.NET Portable Subset和.NET Portable Subset(Legacy)有什么区别?
在便携式设备中,我们有两种方法可以实现可移植性,具体取决于您是针对我们称之为旧版平台还是新平台。
对于传统平台(Phone 7.x,SL4 / 5,.NET 4,Xbox),当我们提出多个平台之间的交叉点时,我们需要物理生成代表公共API的实际程序集。例如,当您组合Windows Phone 7和.NET Framework时,我们生成(这些是在我们这边生成的)一个实际的mscorlib,system,system.core等,它们包含这些共享的API。这不仅非常耗时,而且还可能产生非常有用的子集,这也是非常有问题的。例如,当我们首次跨平台生成网络堆栈的子集时,甚至没有办法创建一种创建HttpWebRequest连接的通用方法。这是因为在较旧的平台上(无论出于何种原因)没有人考虑过可移植性。
对于新平台(.NET 4.5,Windows Store,Phone 8),我们退后一步,设计了可移植性。我们设计了一个代表自包含代码单元的契约(基本上是程序集),而不是尝试将可移植性作为事后的想法,这些代码是平台支持全部或不支持的全部代码。这意味着当您在.NET Framework 4.5上看到“System.IO 4.0.0.0”时,它支持您在Windows Phone 8上看到的完全相同的API。这使得可移植性非常简单,而不是需要生成用于表示平台交叉的自定义程序集,我们只是在程序集边界处进行子集化。例如,给定一个支持System.Runtime.dll的平台1,System.Reflection.dll和System.Reflection.Emit.dll以及支持System.Runtime.dll和System.Reflection.dll的平台2。当您在便携式中定位这些平台时,我们只需选择System.Runtime.dll和System.Reflection.dll。从长远来看,这使得可移植性更容易理解,因为您可以考虑使用程序集而不是单个API。
为旧版平台公开的表面区域(基于Mscorlib)由 .NET Portable Subset(Legacy)表示,而对于新平台,由 .NET Portable表示子集
使用便携式设备时,我们会尝试隐藏这两个表面区域,但在幕后,我们将您的目标对准第一个或第二个表面区域,具体取决于您的目标平台。
这比我的计划要长很多,但是可以随意提出澄清问题,过去3年我一直在生活和呼吸,所以我倾向于不考虑事情就跳过了。