如何在Silverlight应用程序中使用非Silverlight程序集?

12

我正在进行一个项目(纯粹的业余爱好,“磨练技能”),它有一个统一的后端和多个前端(ASP.NET MVC 1.0/JQuery 和 Silverlight 2)。当我尝试在 Silverlight 2 项目(VS2008)中添加我的业务层程序集时,它被拒绝了,因为它不是 Silverlight 程序集。

有没有一种方法可以在 Silverlight 应用程序中包含和引用非 Silverlight 程序集?

8个回答

12

不,没有。Silverlight运行在完全不同的CLR上,与正常的(桌面)CLR不兼容。它在BCL中有一个不同的API集,并且最重要的是有一个不同的元数据版本号。这两个因素等等阻止了为桌面CLR编译的程序集默认在Silverlight CLR上运行。

所有程序集都必须专门为Silverlight编译。


所以我最好在我的业务层添加Web服务外观,并使用它来在Silverlight应用程序和后端之间通信? - Norbert B.
这是完全正确的,然而如果你看看我发帖中第二个链接,有人想出了一种聪明的方法,可以非常容易地将编译的.NET(桌面)程序集转换为Silverlight程序集。但是你应该小心使用程序集中的代码(也许使用条件语句)。 - Noldorin

8
实际上,虽然困难且可能不是一个好主意,但在Silverlight项目中引用CLR程序集是有可能的。David Betz在他的博客中提供了一个例子。
再次强调,您可能真的不想这样做。Silverlight框架是由经验丰富的工程师开发的,他们对包含什么和不包含什么进行了深思熟虑。考虑一下你认为需要的CLR对象,并尝试理解为什么它们当前不可用以及替代方案是什么。
最后,请记住,您添加的任何CLR对象都将增加下载大小。

3

不行。源csproj必须知道它是一个Silverlight项目。这可能意味着需要保留两个具有相同源“.cs”文件的项目文件。这里有一个方便的csproj技巧 - (从protobuf-net复制而来,在那里我为多个框架执行此操作):

<ItemGroup>
    <Compile Include="..\YourMainProject\**\*.cs" />
</ItemGroup>

那么,您只需要维护一个项目;Silverlight项目从树中获取所有内容。

请注意,Silverlight BCL受到严格限制,并非所有功能都可用。编写适用于常规.NET和Silverlight的代码可能会有难度。

或者,在Silverlight应用程序中使用代理类(例如通过WCF等)。虽然不够丰富,但操作简单。


3

无法引用未针对Silverlight运行时构建的程序集。

我解决此问题的方法是为我的业务程序集创建一个新项目,然后将原始程序集中的所有类添加到其中。关键是在添加它们时,将其作为现有项目添加,并在添加按钮上单击向下箭头并选择“添加为链接”。这样,您仍然只有一个代码库,尽管您可能需要添加一些类,例如ApplicationException,以弥补Silverlight运行时缺少的内容。


还有一个来自CodePlex的项目链接工具可用,它允许您自动保持两个项目同步。这非常适合业务对象。记得从SL --> .NET,否则您将有可能再次构建不可用的元素 :-) - Mark Cooper

3
很抱歉,短暂的回答是不行的。Silverlight运行时被设计成.NET框架的子集,但两者并不直接兼容。(我相信,这些运行时的实现方式有很大的不同,因为Silverlight被设计成跨平台的。)
然而好消息是,你有许多解决方法。这篇博客文章这篇CodeProject文章深入讨论了这个问题,并提供了各种干净的解决方案。希望这可以帮到你...

2
警告:我的经验来自于开发 Windows Phone 7,因此这可能与普通的 Silverlight 3 有些微妙的不同。
JaredPar 指出 Silverlight CLR 与普通 CLR 不兼容。这并非完全正确,因为编译为 Windows 库的程序集仍将在 Silverlight 下工作,假设它们使用受支持的 API。 您可以手动编辑 Silverlight 项目并添加对普通 .NET 程序集的引用。请注意,您只能添加对已编译程序集的引用,而不能添加对项目的引用。
Silverlight 应用程序将被编译和运行,但是一旦它尝试使用 Silverlight 中不存在的类,就会出现运行时错误。
为了演示 API 的差异,请查看以下截图。正如您所看到的,这两个程序集具有一些共同的 API,但 Silverlight 版本缺少一些。一旦您的程序集尝试使用那些 API,应用程序就会崩溃!
完整的 .NET 4.0 mscorlib(System.serialization 命名空间): 完整的 .NET 4.0 mscorlib http://img188.imageshack.us/img188/2131/fullmscorlib.png

Silverlight 3 mscorlib (System.serialization namespace):

Silverlight 3 mscorlib http://img526.imageshack.us/img526/4254/sl3mscorlib.png

链接完整的.NET程序集的缺点是,直到运行时你才会知道哪些API不受支持。考虑到潜在地一些受支持的系统API可能使用不受支持的系统API,因此没有简单的方法可以提前解决这个问题。

有一些事情可以让并行开发更容易。Microsoft推荐的方法是为.NET和Silverlight分别创建项目,它们共享相同的源代码。您可以通过将文件作为链接添加到项目中来手动执行此操作。这可能会导致维护上的一些麻烦,但至少大多数错误都会在编译时被捕获。

因此,现在当您编译引用Silverlight缺失API的内容时,您会收到一个错误:

public class SerializableExample: IEquatable<string>, System.Runtime.Serialization.ISerializable
{
}

错误 CS0234:命名空间“System.Runtime.Serialization”中不存在类型或命名空间名称为“ISerializable”(是否缺少程序集引用?)
通过条件编译(类似于早期的C/C++)的帮助,您可以禁用不受支持的内容。
public class SerializableExample: IEquatable<string>
#if !SILVERLIGHT
  , System.Runtime.Serialization.ISerializable
#endif
{
}

微软还提供了一个Project Linker工具,可以自动维护链接文件的项目。不幸的是,当前版本不支持VS2010,你可能可以编译源代码并使其运行,但我没有尝试过。

http://msdn.microsoft.com/en-us/library/dd458870.aspx

直接下载链接:

http://download.microsoft.com/download/6/3/8/6382E28D-2EBD-4A4E-BB76-6F425E1C9DB9/MicrosoftPracticesProjectLinkerFeb2009.msi

这个Microsoft页面详细描述了多目标定位。

1

1

Silverlight 运行时是主 .Net CLR 的一个子集。虽然这看起来可能很麻烦,但有一个明智的原因 - Silverlight 运行时需要足够轻便以成为浏览器插件。

如果将其他类放置在 Web 服务后面,则可以在完整的 .Net 运行时下运行它们,而 Silverlight 应用程序则在浏览器插件中使用精简的 CLR 运行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接