I've been wrestling with this issue for about two weeks now and have cut it back to one very specific test.
Bascially I've got a session factory which configures the NHibernate session factory and has a function which [Export(typeof(ISession))].
The code for this class is as follows:
[Export(typeof(SessionFactoryMock))]
[PartCreationPolicy(CreationPolicy.Shared)]
public class SessionFactoryMock
{
private readonly ISessionFactory sessionFactory;
public SessionFactoryMock()
{
sessionFactory =
Fluently.Configure()
.Database(
MsSqlConfiguration.MsSql2008.ConnectionString(c => c
.Server(@".\SQLExpress")
.Database("Test")
.TrustedConnection()))
.Mappings(configuration => configuration.FluentMappings.Add<TestEntityMap>())
.ExposeConfiguration(c => new SchemaExport(c).Execute(true, true, false))
.BuildSessionFactory();
}
[Export(typeof(ISession))]
public ISession GetSession()
{
return sessionFactory.OpenSession();
}
}
And I'm using the following test:
[TestMethod]
public void CanGetISession()
{
Assembly executing = Assembly.GetExecutingAssembly();
var cat = new AggregateCatalog(new[]
{
new AssemblyCatalog(executing)
});
var container = new CompositionContainer(cat);
var batch = new CompositionBatch();
batch.AddExportedValue(container);
container.Compose(batch);
var compositionInfo = new CompositionInfo(cat, container);
using (var stringWriter = new StringWriter())
{
CompositionInfoTextFormatter.Write(compositionInfo, stringWriter);
string compositionDetail = stringWriter.ToString();
bool errorDetected = compositionDetail.Contains("[Primary Rejection]");
if (errorDetected)
{
Assert.Fail(compositionDetail);
}
}
var export = container.GetExport<ISession>();
var exportedValue = export.Value;
Assert.IsNotNull(exportedValue);
}
This test will continually fail with the message:
System.ComponentModel.Composition.CompositionContractMismatchException: Cannot cast the underlying exported value of type 'MefnHibernateFail.SessionFactoryMock.GetSession (ContractName="NHibernate.ISession")' to type 'NHibernate.ISession'.
Which is extremely unhelpful.
I'm building all the Fluent nHibernate and NHibernate libraries from code and I have an example solution.
I'm really hoping someone can shed some light on this because I'm pretty much at a dead end now.
Full source code can be found here: Source
For anyone else having the same issue. The problem was that the export on the function should be [Export(typeof(Func<ISession>)]
not [Export(typeof(ISession))]
. MEF passes the function pointer not the pointer to the returned object (which is why my function was never called).