gpt4 book ai didi

c#-4.0 - 如何扩展 MEF 以根据作为属性提供的工厂类型创建对象?

转载 作者:行者123 更新时间:2023-12-02 00:22:18 25 4
gpt4 key购买 nike

考虑以下使用 MEF 的现有类组成Consumer

public interface IProducer
{
void Produce();
}

[Export(typeof(IProducer))]
public class Producer : IProducer
{
public Producer()
{
// perform some initialization
}

public void Produce()
{
// produce something
}
}

public class Consumer
{
[Import]
public IProducer Producer
{
get;
set;
}

[ImportingConstructor]
public Consumer(IProducer producer)
{
Producer = producer;
}

public void DoSomething()
{
// do something
Producer.Produce();
}
}

但是,Producer 的创建已经变得非常复杂,无法再在构造函数中完成,默认行为也不再足够。

我想介绍一个工厂并使用生产者本身的自定义 FactoryAttribute 注册它。这就是我的想法:

[Export(typeof(IProducer))]
[Factory(typeof(ProducerFactory))]
public class Producer : IProducer
{
public Producer()
{
// perform some initialization
}

public void Produce()
{
// produce something
}
}

[Export]
public class ProducerFactory
{
public Producer Create()
{
// Perform complex initialization
return new Producer();
}
}

public class FactoryAttribute : Attribute
{
public Type ObjectType
{
get;
private set;
}

public FactoryAttribute(Type objectType)
{
ObjectType = objectType;
}
}

如果我必须自己编写"new"代码,它很可能如下所示。它将使用工厂属性(如果存在)来创建部件,或者默认使用 MEF 来创建部件。

public object Create(Type partType, CompositionContainer container)
{
var attribute = (FactoryAttribute)partType.GetCustomAttributes(typeof (FactoryAttribute), true).FirstOrDefault();
if (attribute == null)
{
var result = container.GetExports(partType, null, null).First();
return result.Value;
}
else
{
var factoryExport = container.GetExports(attribute.ObjectType, null, null).First();
var factory = factoryExport.Value;
var method = factory.GetType().GetMethod("Create");
var result = method.Invoke(factory, new object[0]);
container.ComposeParts(result);
return result;
}
}

有很多文章如何实现 ExportProvider,包括:

  1. MEF + Object Factories using Export Provider
  2. Dynamic Instantiation

然而,这些例子并不理想

  1. 应用程序不依赖于Producer,也不了解Producer。创建 CompositionContainer 时,它将无法注册工厂。
  2. Producer 被多个应用程序重用,开发人员可能会错误地忘记在创建 CompositionContainer 时注册工厂。
  3. 有大量类型需要自定义工厂,在创建 CompositionContainer 时记住注册工厂可能会造成维护噩梦。

我开始创建一个 ExportProvider(假设这将提供使用工厂实现构造的方法)。

public class FactoryExportProvider : ExportProvider
{
protected override IEnumerable<Export> GetExportsCore(ImportDefinition definition,
AtomicComposition atomicComposition)
{
// What to do here?
}
}

但是,我无法理解如何告诉 MEF 使用 FactoryAttribute 中定义的工厂对象,并在不存在此类属性时使用默认创建机制。

实现这个的正确方法是什么?我正在使用 MEF 2 Preview 5和 .NET 4。

最佳答案

您可以使用属性导出:

public class ProducerExporter
{
[Export]
public IProducer MyProducer
{
get
{
var producer = new Producer();
// complex initialization here
return producer;
}
}
}

请注意,术语工厂 并不真正适合您的示例,我会保留该术语,用于导入程序可能通过提供一个或多个参数来随意创建实例的情况。这可以通过方法导出来完成:

public class ProducerFactory
{
[Export(typeof(Func<Type1,Type2,IProducer>)]
public IProducer CreateProducer(Type1 arg1, Type2 arg2)
{
return new Producer(arg1, arg2);
}
}

在导入端,您将导入 Func<Type1,Type2,IProducer>您可以随意调用以创建新实例。

关于c#-4.0 - 如何扩展 MEF 以根据作为属性提供的工厂类型创建对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10377206/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com