ChangeRejectedException on compose Silverlight MVVM test

Dec 22, 2009 at 7:25 AM

I'm trying to create a simple Silverlight 4 application using MEF and MVVM.

I have a ViewModel class exporting itself:
    [Export("ProgramListViewModel")]
    public class ProgramListViewModel : BerViewModelBase {
        private IBerModel model;

        [ImportingConstructor]
        public ProgramListViewModel(IBerModel theModel) {
            model = theModel;
        }
    }

And Silverlight Test class:
    [TestClass]
    public class ProgramListViewModelTests : SilverlightTest {
        [Import("ProgramListViewModel")]
        public ProgramListViewModel ViewModel { get; set; }

        [TestInitialize]
        public void TestInitialize() {
            PartInitializer.SatisfyImports(this);
        }

        [TestMethod]
        public void TestBasics() {
            Assert.IsNotNull(ViewModel, "Failed to retrieve the viewmodel via MEF");
        }
    }

Toresolve dependency on IBerModel I have BerModelFake class in test assembly:
    [Export(typeof(IBerModel))]
    public class BerModelFake : IBerModel {
        ...
    }

I'm getting the following exception on calling PartInitializer.SatisfyImports(this) in TestInitialize

System.ComponentModel.Composition.ChangeRejectedException was unhandled by user code
  Message=The composition remains unchanged. The changes were rejected because of the following error(s): The composition produced a single composition error. The root cause is provided below. Review the CompositionException.Errors property for more detailed information.

1) No valid exports were found that match the constraint '((exportDefinition.ContractName == "Intel.Ber.Client.ViewModel.ProgramListViewModel") AndAlso (exportDefinition.Metadata.ContainsKey("ExportTypeIdentity") AndAlso "Intel.Ber.Client.ViewModel.ProgramListViewModel".Equals(exportDefinition.Metadata.get_Item("ExportTypeIdentity"))))', invalid exports may have been rejected.

Resulting in: Cannot set import 'Intel.Ber.Client.Tests.ProgramListViewModelTests.ViewModel (ContractName="Intel.Ber.Client.ViewModel.ProgramListViewModel")' on part 'Intel.Ber.Client.Tests.ProgramListViewModelTests'.
Element: Intel.Ber.Client.Tests.ProgramListViewModelTests.ViewModel (ContractName="Intel.Ber.Client.ViewModel.ProgramListViewModel") -->  Intel.Ber.Client.Tests.ProgramListViewModelTests

  StackTrace:
       at System.ComponentModel.Composition.CompositionResult.ThrowOnErrors(AtomicComposition atomicComposition)
       at System.ComponentModel.Composition.Hosting.ComposablePartExportProvider.Compose(CompositionBatch batch)
       at System.ComponentModel.Composition.Hosting.CompositionContainer.Compose(CompositionBatch batch)
       at System.ComponentModel.Composition.PartInitializer.SatisfyImports(Object instance)
       at Intel.Ber.Client.Tests.ProgramListViewModelTests.TestInitialize()
  InnerException:

Please point me what am I doing wrong?

Thanks,
Anton

Dec 23, 2009 at 5:47 AM

First I got somewhat similar problem with WPF (that wasn’t using PRISM),

I solve that problem on my solution by playing with the composition place,

I tried to compose at the App.xaml startup but finally I did it on the main form

protected override void OnInitialized(EventArgs e)  {
    base.OnInitialized(e);
    var asmCatalog = new AssemblyCatalog(typeof(App).Assembly);
    var container = new CompositionContainer(asmCatalog);
    container.ComposeParts(this);
    DataContext = this;
}

 

but that’s was for WPF.

As for Silverlight you can try different approach rather than using the PartInitializer,
you can check for how did I do it on the following post
http://blogs.microsoft.co.il/blogs/bnaya/archive/2009/12/19/mef-for-beginner-part-3-hello-silverlight.aspx

You can find the link for the source code within the post