假定我要用Silverlight類庫實作一些通用控件,然後在應用程式中引用這個控件庫。當然,控件通常也要通路其他一些第三方或開源的開發包,例如Silverlight Toolkit。
于是這個項目的依賴關系如下: Silverlight Application => Silverlight Control => Silverlight Toolkit。在Visual Studio中建立好項目之間的引用關系:

然後在類庫項目中建立一個簡單的控件,比如:
<UserControl x:Class="SLLib.TestControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"Â
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Â
    xmlns:controlsToolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Toolkit"Â
    >
    <Grid x:Name="LayoutRoot">
        <controlsToolkit:DockPanel>
        controlsToolkit:DockPanel>
    Grid>
UserControl>
最後,在應用程式中添加我們剛剛建立的控件:
<UserControl x:Class="TestSL.MainPage"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"Â
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"Â
    mc:Ignorable="d"
    xmlns:lib="clr-namespace:SLLib;assembly=SLLib">
   Â
        <lib:TestControl />
這麼簡單的程式(一行代碼也沒有),不可能出問題吧?可惜事實上不是這樣:
原因在哪呢?我們打開.xap 檔案看看,就會發現問題:Toolkit程式集竟然沒有被包含進來!這樣控件運作的時候是無法找到DockPanel類的,程式自然就出錯了。
我們可以從其他方面來驗證這個錯誤。删掉原來的控件(其實不删也可以) ,從代碼建立一個控件:
public class TestControl2 : ContentControl
{
public TestControl2()
{
this.Content = new DockPanel();
}
}
然後把程式中的TestControl換成TestControl2,再試試看怎麼樣?運作正常!.xap檔案現在也包含Toolkit了:
另一方面,如果我們在應用程式的引用中手工加上System.Windows.Controls.Toolkit,那麼程式也可以運作正常。
這些迹象表明,Silverlight編譯器實在有點自作聰明。即使我們在類庫引用中明确指定了要引用的程式集,編譯器也會忽略這些訓示,隻查找代碼中使用到的那些。對于你在.xaml中引用的程式集,編譯器根本不予理會。讓情況更加惡化的是,如果運作時找不到類,那麼Silverlight運作時隻會抛出臭名卓著的AG_E_PARSER_BAD_TYPE,這個毫無内容的錯誤資訊對查找問題沒有什麼幫助。奇怪的是對于Application類型的項目,Silverlight編譯器的做法則完全不同——隻要在項目引用中加入了任何程式集,無論實際上是否被用到,都會編譯到最終的.xap檔案中。這種不一緻的行為是你應當小心的。
此問題最簡單的work around就是:隻要在類庫中引用了哪些程式集,在應用程式中也保證引用同樣的程式集,就可以避免出現錯誤。顯然這不是一個很理想的辦法,不僅因為它迫使程式員重複做一些沒有實際意義的工作,也使得類庫的使用者不得不去關心類庫的内部機制,進而讓類庫的存在意義大打折扣。