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

时间:2009-04-06 13:14:02

标签: .net silverlight silverlight-2.0

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

他们是否可以在Silverlight应用中包含和引用非Silverlight程序集?

9 个答案:

答案 0 :(得分:12)

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

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

答案 1 :(得分:8)

实际上,虽然很难并且可能不是一个好主意,但可以在Silverlight项目中引用CLR程序集。 David Betz在他的博客上有一个例子: http://www.netfxharmonics.com/2008/12/Reusing-NET-Assemblies-in-Silverlight

同样值得强调的是,你可能并不真的想要这样做。 Silverlight框架由经验丰富的工程师开发,他们对应该包含哪些内容以及哪些不应该包含哪些内容进行了大量思考。考虑一下您认为需要的CLR对象,并尝试理解它们目前​​不可用的原因,以及替代方案。

最后,请记住,您添加的任何CLR对象都会增加下载的大小。

答案 2 :(得分:3)

不可能引用不是针对Silverlight运行时构建的程序集。

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

答案 3 :(得分:3)

简短的回答是不,我害怕。 Silverlight运行时被设计为.NET框架的一个子集,但两者不是直接兼容的。 (我相信,运行时的实现方式完全不同,因为Silverlight被设计为跨平台。)

然而,好消息是你有大量的解决方法。 This blog postthis CodeProject文章深入讨论了这个问题,并提供了各种清洁解决方案。希望有所帮助...

答案 4 :(得分:3)

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

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

然后你只需要维护一个项目; Silverlight项目从树中获取所有内容。

请注意,Silverlight BCL受到严格限制,并非所有功能都可用。获取在常规.NET和Silverlight上编译的代码可能具有挑战性。

或者,在Silverlight应用程序中使用代理类(即通过WCF等)。不是那么富有,而是很容易做到。

答案 5 :(得分:2)

一句警告,我对此的体验来自Windows Phone 7的开发,因此这可能与普通的Silverlight 3略有不同。

JaredPar指出Silverlight CLR与普通CLR不兼容。这不是100%正确,因为编译为Windows库的程序集仍然可以在silverlight 下工作,假设它们使用支持的API。您可以手动编辑silverlight项目并添加对普通.NET程序集的引用。请注意,您只能添加对已编译程序集的引用,而不能添加项目。

Silverlight应用程序将编译并运行,但只要它尝试使用Silverlight中不存在的类,就会出现运行时错误。

要演示API的不同之处,请查看以下屏幕截图。正如您所看到的,这两个程序集有一些常见的API,但Silverlight有一些缺失。一旦你的程序集试图点击那些API,应用就会变成BOOM!

完整的.NET 4.0 mscorlib(System.serialization命名空间):

Full .NET 4.0 mscorlib http://img188.imageshack.us/img188/2131/fullmscorlib.png

Silverlight 3 mscorlib(System.serialization名称空间):

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'(您是否缺少程序集引用?)

借助条件编译(a-la good ol'C / C ++ days),您可以禁用不受支持的内容:

public class SerializableExample: IEquatable<string>
#if !SILVERLIGHT
  , System.Runtime.Serialization.ISerializable
#endif
{
}

Microsoft还提供了一个项目链接器工具,允许自动维护具有链接文件的项目。不幸的是,目前的版本不能在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 page描述了难以捉摸的细节中的多目标定位。

答案 6 :(得分:1)

Silverlight运行时是主.Net CLR的子集。虽然这看起来很痛苦但是有一个合理的理由 - Silverlight运行时需要足够轻才能成为浏览器插件。

如果您将其他类放在webservices后面,那么当您的Silverlight应用程序在浏览器插件中的剪切CLR下运行时,它们可以在完整的.Net运行时下运行。

答案 7 :(得分:1)

你试过这个吗?它可以通过右键单击.NET库项目直接构建Silverlight程序集。

http://buildassilverlight.codeplex.com/

答案 8 :(得分:1)

迟到回答,但将此链接添加到assembly-level vs. file-level reuse。这是非常彻底的。