2012-02-17 69 views
0

我目前正在与MEF合作开发MVC Web应用程序,以便a)开发人员可以为该网站开发插件,并且用户可以选择他们想要的帐户插件。这意味着我的一些作文必须在应用程序已经启动并且用户已经登录之后才会发生(它进入数据库,抓取插件的程序集并将它们添加到当前目录中)。在运行时更新MEF目录

它的工作方式是我有一些库存储在数据库中,当用户登录时加载到AssemblyCatalog中,我可以在我的Composer中成功添加到我现有的AggregateCatalog中。但是,在我的一个库中,我有一个IController合约没有被导出,导致特定的小部件崩溃。我不完全确定如何强制MEF在启动后重新组合。我在这里张贴,希望有人对我有一些建议。

我的代码是基于excellent blog series by Matt Abbott的,所以我很希望他会提供一些建议。

+0

感谢您修复链接,莱斯特。 :) 非常感激。 – 2012-02-18 16:08:09

回答

1

嘛,不能你只需加载所有可用的零件(无论哪个客户有他们启用),但使用延迟的实例化,无论是通过LazyExportFactory与元数据的组合来识别部件到客户端系统?这样你就不需要按需加载程序集,他们只是准备好了。

如果您希望从数据库中动态读取程序集并将其加载到AppDomain中,则可以将其封装到新的AssemblyCatalog中,但要利用重新组合。例如,在那个早期版本中,我使用的是PartCreator<T,TMetadata>,它发展为ExportFactory<T,TMetadata>附近的版本(但不包括在最终的.NET 4.0中)。如果更改[ImportMany][ImportMany(AllowRecomposition = true)],下一次你添加一个新的目录,例如:

((AggregateCatalog)container.Catalog).Catalogs.Add(<assembly>); 

哪些应该重新构图[ImportMany]PartCreatorExportFactory)实例。

不知道这会工作......我需要了解你的意图架构之前,我可以说,它会或不会工作...

+0

马修,你好!基本上,我使用的是您的博客系列第3部分中链接的代码版本,没有发生重大更改。我*可以*加载所有插件/小部件,但是通过我们对这个站点的计划,这可能意味着为所有客户端加载了数百个程序集,这可能是不可能的。所以我在运行时按需加载。 我还没有尝试AllowRecomposition属性,所以我会给这个旋转,看看会发生什么。 :) 感谢您的回复! – 2012-02-18 16:06:54

+0

AllowRecomposition似乎适用于启动后加载的程序集,只是这些程序集中的一个程序集具有IController导出,似乎不会为ImportControllerFactory重新组合,因此对该控制器/操作的任何请求都会失败。我愿意向你发送一些代码来看待,这会很酷吗? – 2012-02-28 14:55:34

0

我进入这个作为一个答案,即使这不是一个真正的答案,而是更多的结论。我的问题是这样的:我在应用程序启动时完成了我的所有MEF组合,然后在用户登录后尝试将其全部分开。

实际上,我只需要推迟所有这些。让用户先登录,然后根据用户“安装”的内容(从数据库中提取程序集等)完成我所有的MEF组合,将该组合容器存储在会话或其他存储机制中(这样我可以获得导出根据需要构建页面,小部件等),而我是金。我最初的问题是因为试图将一个方形钉子安装到一个圆孔中而产生的。我的作文不需要登录才能发生,不需要启动。虽然我可能会使用MEF在我的应用程序中执行一些DI,但这与用户组合是分开的。

不过,我要再次感谢Matthew Abbott在MEF和MVC上的精彩演讲,这真的有助于推动这一应用的发展。 :)我没有将他的答案标记为答复,但我确实赞成这个答案,以帮助他获得更多的声誉。