使用mef时,Caliburn micro无法找到MainView

时间:2015-11-02 16:19:15

标签: c# wpf mef caliburn.micro

我目前有点无能为力。我正在使用带有MEF的Caliburn微框架。 主应用程序应该加载基本上只包含服务功能的插件。但是一旦我引用外部程序集,CaliburnMicro就会拒绝找到MainWindowView(如果没有引用外部程序集,它就可以正常工作)。

我的Bootstrapper(基本上是CM示例中的那个):

public class AppBootstrapper : BootstrapperBase
{
    private CompositionContainer container;

    public AppBootstrapper()
    {
        Initialize();
    }

    protected override void Configure()
    {
        container = new CompositionContainer(
            new AggregateCatalog(
                AssemblySource.Instance.Select( x => new AssemblyCatalog( x ) ).OfType<ComposablePartCatalog>()
                )
            );

        var batch = new CompositionBatch();

        batch.AddExportedValue<IWindowManager>( new WindowManager() );
        batch.AddExportedValue<IEventAggregator>( new EventAggregator() );
        batch.AddExportedValue( container );

        container.Compose( batch );
    }

    protected override object GetInstance( Type serviceType, string key )
    {
        var contract = string.IsNullOrEmpty( key ) ? AttributedModelServices.GetContractName( serviceType ) : key;
        var exports = container.GetExportedValues<object>( contract );

        if ( exports.Any() )
            return exports.First();

        throw new Exception( $"Could not locate any instances of contract {contract}." );
    }

    protected override IEnumerable<object> GetAllInstances( Type serviceType )
    {
        return container.GetExportedValues<object>( AttributedModelServices.GetContractName( serviceType ) );
    }

    protected override void BuildUp( object instance )
    {
        container.SatisfyImportsOnce( instance );
    }

    protected override void OnStartup( object sender, StartupEventArgs e )
    {
        base.OnStartup( sender, e );
        DisplayRootViewFor<IMainWindow>();
    }
}

我的主窗口

[Export( typeof( IMainWindow ) )]
public class MainWindowViewModel : Conductor<IShell>, IMainWindow, IPartImportsSatisfiedNotification
{
    private string _title = "Title";

    public string Title
    {
        get { return _title; }
        set
        {
            _title = value;
            NotifyOfPropertyChange( () => Title );
        }
    }

    private ImageSource _icon;

    public ImageSource Icon
    {
        get { return _icon; }
        set
        {
            _icon = value;
            NotifyOfPropertyChange( () => Icon );
        }
    }

    [Import]
    private IResourceManager _resourceManager;

    [Import]
    private IShell _shell;

    public IShell Shell
    {
        get { return _shell; }
        private set
        {
            _shell = value;
            NotifyOfPropertyChange( () => Shell );
        }
    }

    public void OnImportsSatisfied()
    {
        if ( Icon == null )
            Icon = _resourceManager.GetBitmap( "Resources/Icons/icon.ico" );
    }
}

Shell和ResourceManager位于主程序集/可执行文件中(与MainWindow / Bootstrapper相同)。

我尝试从外部程序集导出接口并使用ShellViewModel导入它。

我的ShellViewModel

[Export( typeof ( IShell ) )]
public class ShellViewModel : PropertyChangedBase, IShell
{
    [Import]
    private ITestInterface _testInterface;

    public ITestInterface TestInterface
    {
        get { return _testInterface; }
        set { _testInterface = value; }
    }
}

我的外部装配:

public interface ITestInterface
{
    string Test();
}

[Export(typeof(ITestInterface))]
public class MyTest : ITestInterface
{
    public string Test()
    {
        return "Test ok";
    }
}

1 个答案:

答案 0 :(得分:1)

找到解决方案:

        protected override void Configure()
    {
        container = new CompositionContainer( new ApplicationCatalog() );

        var batch = new CompositionBatch();

        batch.AddExportedValue<IWindowManager>( new WindowManager() );
        batch.AddExportedValue<IEventAggregator>( new EventAggregator() );
        batch.AddExportedValue( container );

        container.Compose( batch );
    }

AggregateCatalog更改为ApplicationCatalog解决了这个问题。