我正在使用Silverlight 4 RC中的应用程序,我正在考虑学习MEF来处理插件控件。我已经让它在一个非常基本的庄园工作,但它并不完全整洁,我知道有更好的方法可以导入多个xap。
基本上,在我的主机应用程序的App.xaml中,我有以下告诉MEF加载我的xap:
AggregateCatalog catalog = new AggregateCatalog();
DeploymentCatalog c1 = new DeploymentCatalog(new Uri("TestPlugInA.xap", UriKind.Relative));
DeploymentCatalog c2 = new DeploymentCatalog(new Uri("TestPlugInB.xap", UriKind.Relative));
catalog.Catalogs.Add(c1);
catalog.Catalogs.Add(c2);
CompositionHost.Initialize(catalog);
c1.DownloadAsync();
c2.DownloadAsync();
我确定我没有在这里完全使用AggregateCatalog,我需要能够加载可能在目录中的任何xap,而不仅仅是对Uri进行硬编码....
此外,在主机的MainPage.xaml.cs中,我有以下集合,MEF将插件放入:
[ImportMany(AllowRecomposition = true)]
public ObservableCollection<IPlugInApp> PlugIns { get; set; }
同样,这有效,但我很确定我正在使用ImportMany错误....
最后,MainPage.xaml.cs文件实现了IPartImportsSatisfiedNotification,我有以下内容用于处理插件一旦加载:
public void OnImportsSatisfied()
{
sp.Children.Clear();
foreach (IPlugInApp plugIn in PlugIns)
{
if (plugIn != null)
sp.Children.Add(plugIn.GetUserControl());
}
}
这样可行,但它运行n次似乎是肮脏的(n是要加载的xap的数量)。我必须调用sp.Children.Clear(),就好像我没有,当加载2插件时,我的堆栈面板填充如下:
TestPlugIn A. TestPlugIn A. TestPlugIn B
我在这里显然遗漏了一些东西。谁能指出我应该做什么? 谢谢!
答案 0 :(得分:1)
我认为你做的大部分都很好。尽管ObservableCollections确实支持添加和删除单个元素的通知,但MEF并未利用此功能。在您的情况下,它将简单地清除集合,然后添加所有插件。由于您使用OnImportsSatisfied进行更改通知,因此您甚至不需要ObservableCollection。您可以使用IEnumerable进行导入。
为了增加下载不同xaps的灵活性,我会在容器中公开一个可以导入的服务,并提供下载给定URL的xap的功能。然后容器中的任何组件都可以触发下载,下载的URL可以来自您认为合适的任何来源。