Open
Description
The following code sample shows two types MyController and MyViewModel which have a cyclic dependency to each other (decoupled via the IBaz interface). Both types are Shared. The test code at the bottom gets MyController via IFoo and IBaz export.
I expect that foo and baz reference the same MyController instance because it is shared. Unfortunately, MEF2 creates two instances of MyController. That's a bug.
MEF1 behaves correct - see second code snippet.
// MEF2 Issue:
// C# Console (.NET Framework) and NuGet package "System.Composition" 1.0.31
using System;
using System.Composition;
using System.Composition.Hosting;
using System.Reflection;
public interface IFoo { }
public interface IBaz { }
[Export(typeof(IFoo)), Export(typeof(IBaz)), Shared]
public class MyController : IFoo, IBaz
{
[ImportingConstructor]
public MyController(Lazy<MyViewModel> myViewModel)
{
}
}
[Export, Shared]
public class MyViewModel
{
[ImportingConstructor]
public MyViewModel(IBaz baz)
{
}
}
internal static class Program
{
internal static void Main()
{
var container = new ContainerConfiguration()
.WithAssembly(typeof(MyController).GetTypeInfo().Assembly).CreateContainer();
var foo = container.GetExport<IFoo>();
var baz = container.GetExport<IBaz>();
bool areSame = ReferenceEquals(foo, baz);
Console.WriteLine(areSame); // Output: false
}
}
The second code sample shows the same scenario with MEF1. The behavior here is correct.
// MEF1 behaves correct
// C# Console (.NET Framework) and reference "System.ComponentModel.Composition"
using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
public interface IFoo { }
public interface IBaz { }
[Export(typeof(IFoo)), Export(typeof(IBaz)), PartCreationPolicy(CreationPolicy.Shared)]
public class MyController : IFoo, IBaz
{
[ImportingConstructor]
public MyController(Lazy<MyViewModel> myViewModel)
{
}
}
[Export, PartCreationPolicy(CreationPolicy.Shared)]
public class MyViewModel
{
[ImportingConstructor]
public MyViewModel(IBaz baz)
{
}
}
internal static class Program
{
internal static void Main()
{
var container = new CompositionContainer(
new AssemblyCatalog(typeof(MyController).Assembly),
CompositionOptions.DisableSilentRejection);
var foo = container.GetExportedValue<IFoo>();
var baz = container.GetExportedValue<IBaz>();
bool areSame = ReferenceEquals(foo, baz);
Console.WriteLine(areSame); // Output: true
}
}