Вот, пожалуйста. Класс Test
импортирует экземпляр IFoo
через конструктор:
public class Program
{
public static void Main(string[] args)
{
var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
var container = new CompositionContainer(catalog);
Test test = container.GetExportedValue<Test>();
}
}
[Export]
public class Test
{
private IFoo foo;
[ImportingConstructor]
public Test(IFoo foo)
{
this.foo = foo;
}
}
public interface IFoo
{
}
[Export(typeof(IFoo))]
public class Foo : IFoo
{
}
изменить в ответ на комментарий: Я предполагаю, что под «инициализирован нами, а не совместно используемым» вы имеете в виду, что вы хотите вручную создать экземпляр класса без атрибутов, не MEF и внедрить его как зависимость для части MEF. Обычно вы делаете это так:
public class Program
{
public static void Main(string[] args)
{
var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
var container = new CompositionContainer(catalog);
// create and add non-MEF instance explicitly to container
var nonMEF = new NonMefClass();
container.ComposeExportedValue<IFoo>("Test.foo", nonMEF);
Test test = container.GetExportedValue<Test>();
}
}
[Export]
public class Test
{
private IFoo foo;
[ImportingConstructor]
public Test([Import("Test.foo", typeof(IFoo))] IFoo foo)
{
this.foo = foo;
}
}
public interface IFoo
{
}
public class NonMefClass : IFoo
{
}
Альтернативой явному добавлению экземпляров в контейнер с ComposeExportedValue
является использование свойство export . Затем вы можете инициализировать объект не MEF, как вы хотите, в получателе свойства:
public class Bar
{
[Export("Test.foo", typeof(IFoo))]
public IFoo Foo
{
get
{
return new NonMefClass();
}
}
}
изменить в ответ на комментарий2 : сначала предупреждение; Кажется, что ImportingConstructor и PartCreator не очень хорошо сочетаются друг с другом в MEF preview 8, возможно, потому, что PartCreator - это всего лишь пример, который еще не был хорошо протестирован. Используйте внедрение свойства для импорта экземпляров PartCreator.
Теперь, чтобы ответить на ваш вопрос; если вы просто хотите заставить MEF создать несколько экземпляров зависимости, то вам просто нужно присвоить импорту [Import("Test.foo", typeof(IFoo), RequiredCreationPolicy=CreationPolicy.NonShared)]
.
Если вам нужны совершенно разные композиции для каждого экземпляра, то все немного сложнее. В действительности вы не можете иметь единственную часть (то есть класс с атрибутами MEF), и она будет составлена по-разному для разных экземпляров детали, если вы не настроите несколько контейнеров. Вместо этого я делаю в таких случаях несколько частей, которые наследуются от общего класса. Затем у вас есть 1 подкласс для каждой желаемой композиции:
public class Test
{
private IFoo foo;
public Test(IFoo foo)
{
this.foo = foo;
}
}
[Export]
public class TestComposition1 : Test
{
[ImportingConstructor]
public Test([Import("TestComposition1.foo", typeof(IFoo))] IFoo foo)
: base(foo)
{
}
}
[Export]
public class TestComposition2 : Test
{
[ImportingConstructor]
public Test([Import("TestComposition2.foo", typeof(IFoo))] IFoo foo)
: base(foo)
{
}
}
Это, конечно, требует, чтобы вы имели в виду ограниченное количество альтернативных композиций. Если количество желаемых композиций не может быть перечислено во время разработки, вам нужны более сложные вещи, возможно, с участием PartCreator и динамического выбора на основе метаданных детали.