c# 4.0 -在MEF中,如何使用DirectoryCatalog避免不必要的导出类型扫描以提高性能



我有大约20个dll,出口,进口零件。在每个dll中都有一个类,带有导入和导出属性。但是在编写MEF时,会扫描dll中所有可用的类型。

下面的结果仅取自一个dll的输出。

因此,compose方法需要时间。如何避免不必要的类型扫描?

    sample plugin
[ModuleAttibute("MENU")]
[ExportMetadata("SAMPLE", "SAMPLE")]
public class MenuModule : IModule
{
}
    public static bool CheckParts(ComposablePartDefinition partDef)
    {
        var keepPart = (from e in partDef.ExportDefinitions
                        where e.Metadata.ContainsKey("Sample")
                        select e).Any();
        return keepPart;
    }

public class FilteredCatalog : ComposablePartCatalog
{
    private readonly ComposablePartCatalog _inner;
    private readonly Func<ComposablePartDefinition,bool> _partsQuery;
    public FilteredCatalog(ComposablePartCatalog inner, Func<ComposablePartDefinition, bool> expression)
    {
        _inner = inner;
        _partsQuery = expression;
    }
    public override IQueryable<ComposablePartDefinition> Parts
    {
        get
        {
            return FilterParts();
        }
    }
    public  IQueryable<ComposablePartDefinition> FilterParts()
    {
        return (from p in _inner.Parts
                let keepPart = _partsQuery(p)
                where keepPart == true
                select p);
    }
}
var cat1 = new DirectoryCatalog(ConfigurationManager.AppSettings["Path"].Replace("~", exeDirectory), "*PlugIn*.dll");
var filteredCat1 = new FilteredCatalog(cat1, CheckParts);
_catalog.Catalogs.Add(filteredCat1);
var cc1 = new CompositionContainer(_catalog);
cc1.ComposeParts(this);
结果

System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'PlugIn.Core.DbTypes' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'PlugIn.Core.EnvironmentInfo' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'PlugIn.Core.Interfaces.IHost' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'PlugIn.Core.Interfaces.IModule' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'PlugIn.Core.Interfaces.IPlugIn' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'PlugIn.Core.Interfaces.IModuleAttribute' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'PlugIn.Core.Interfaces.IModuleHandler' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'PlugIn.Core.Interfaces.ISNLogin' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'PlugIn.Core.ModuleAttibute' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'PlugIn.Core.FilteredCatalog' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'PlugIn.Core.PlugInBase' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'OneSystem.Shell.Properties.Resources' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'OneSystem.Shell.Properties.Settings' was ignored because it contains no exports.

另一个插件输出,在撰写时花费2000毫秒。项目共扫描400种类型

System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.AppLauncher' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.Bootstrapper' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.FrmMap' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.OverView.FrmOverView' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.OverView.IArrivalDetailsView' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.OverView.ucArrivalDetails' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.OverView.ArrivalDetailsPresenter' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.OverView.ICargoPortDetailsView' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.OverView.ucCargoPortDetails' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.OverView.CargoPortDetailsPresenter' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.OverView.IGeneralPortAgentInfoView' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.OverView.ucPortAgentInfo' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.OverView.PortAgentInfoPresenter' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.OverView.IPieChartActivitiesFactsView' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.OverView.ucPieChartActivities' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.OverView.PieChartActivitiesFactsPresenter' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.OverView.IPortAlertsView' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.OverView.ucPortAlerts' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.OverView.PortAlertsPresenter' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.OverView.IVRSView' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.OverView.ucVRS' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.OverView.VRSPresenter' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.iPositionExplorer' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.FrmPositionExplorerNew' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.FrmAdjustSpeed' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.ICargoDialogView' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.frmCargoDialogBox' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.FormPresenter' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.FrmCreateDADesk' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.FrmCreateDADeskByAgent' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.FrmCreateDADeskByAgentPresenter' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.IFrmCreateDADeskByAgentView' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.FrmDebunker' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.LogAbstractDialogFormView' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.frmLogAbstractDialogBox' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.FormLogAbstractPresenter' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.PerformanceDetailsDialogView' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.frmPerformanceDialogBox' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.PerformanceDetailsDialogPresenter' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.FrmPortCallBunkerDetail' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.FrmROEDialogBox' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.FrmSteamDialogBox' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.IFrmAdjustROBView' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.FrmAdjustROB' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.FrmAdjustROBPresenter' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.FrmBrowser' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.FrmUpdateDADesk' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorerNewPresenter' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.IUserControlView' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.ITabView' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.ucFixtureNote' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.FixtureNotePresenter' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.LogAbstractView' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.ucLogAbstract' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.LogAbstractPresenter' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.ILogAbstractDetailView' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.IPositionDetailTab' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.ucLogAbstractDetails' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.LogAbstractDetailPresenter' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.PerformanceDetailsView' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.ucPerformanceDetails' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.PerformanceDetailsPresenter' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.IPortCallActivityView' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.ucPortCallActivities' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PortCallActivityPresenter' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.IPortCallBunkerDetailView' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.IPortBunkerDetOuterView' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.ucPortCallBunkerDetail' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PortCallBunkerDetailPresenter' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.ICommentsView' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.ucPortCallComments' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.PortCallCommentsPresenter' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.IPortCallDAView' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.ucPortCallDA' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.PortCallDAPresenter' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.IPortCallFactView' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.ucPortCallFact' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.PortCallFactPresenter' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.IPortCallHistory' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.UcPortCallHistory' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.PortCallHistoryPresenter' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.ITaskView' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.ucPortCallTask' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.TaskPresenter' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.UcArrDepPresenter' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.IUcArrDepView' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.ICargoFactView' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.ucCargoFacts' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.CargoFactPresenter' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PortBunkerPresenter' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.IPortBunkerView' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.ICargoView' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.ucCargoes' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.CargoPresenter' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.IUserControlView' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.ucPortLogCargo' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.ucPortLogCargoPresenter' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.ClonePositionCargo' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.IPositionSearchAdditionalView' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.ucPositionSearchAdditional' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.PositionSearchAdditionalPresenter' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.IPositionSearchBasicView' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.ucPositionSearchBasic' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.PositionSearchBasicPresenter' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.IUpdateDADeskView' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.ucUpdateDADesk' was ignored because it contains no exports.
System.ComponentModel.Composition Information: 6 : The ComposablePartDefinition 'ERP.VM.UI.PositionExplorer.UpdateDADeskPresenter' was ignored because it contains no exports.

为了消除扫描,您可以将DirectoryCatalog替换为TypeCatalog,如下所示:

var cat1 = new TypeCatalog(typeof(Type1), typeof(Type2), ...);

但是,您可能希望插件被自动发现。这就是为什么你首先使用DirectoryCatalog,对吗?如果不扫描所有类型来查看导出了哪些类型,则无法完成此操作。

你确定是扫描花了很多时间吗?也许是CheckParts代码(在你的问题中没有显示)减慢了速度。尝试删除FilteredCatalog的使用,以检查其对性能的影响。

edit:我刚刚意识到您可能多次构建组合容器,这就是为什么2秒加载时间是不可接受的。修复方法是仅在应用程序启动时构建一次组合容器

最新更新