我想使用MEF使用队列插件。我已尝试过以下内容,但以下字段queuePlugins和alternativeApproach,使用Import属性进行装饰(在以下示例中)为空 任何的想法? 谢谢, 原子
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.IO;
using System.Linq;
using System.Reflection;
namespace MefIsHell
{
class Program
{
static void Main(string[] args)
{
QueueFactory<string> qf = new QueueFactory<string>();
var queue = qf.GetQueue(QueueProviderType.InProcess);
}
}
public class QueueFactory<T> : IPartImportsSatisfiedNotification where T : class
{
[ImportMany]
private IEnumerable<Lazy<IQueueProviderPlugin<T>, IQueuePluginMetadata>> queuePlugins = null;
[ImportMany(typeof(IQueueProviderPlugin<>))]
private IEnumerable<IQueueProviderPlugin<T>> alternativeApproach;
public QueueFactory ()
{
ComposeMEF();
}
private void ComposeMEF()
{
var catalog = new DirectoryCatalog(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
CompositionContainer container = new CompositionContainer(catalog);
container.ComposeParts(this);
}
public void OnImportsSatisfied()
{
if (!queuePlugins.Any())
{
Console.WriteLine("queuePlugins is empty");
}
if (!alternativeApproach.Any())
{
Console.WriteLine("alternativeApproach is empty");
}
}
public IQueueProviderPlugin<T> GetQueue(QueueProviderType QueueType)
{
var plugins = from lazyPlugin in queuePlugins
let metadata = lazyPlugin.Metadata
where metadata.QueueType == QueueType
select lazyPlugin.Value;
if (plugins.Count() == 0)
{
throw new ApplicationException("No plugins!!!");
}
return plugins.First();
}
}
public interface IQueueProviderPlugin<T>
{
void Enqueue(T item);
T Dequeue();
}
public enum QueueProviderType
{
InProcess,
RabbitMQ
}
public interface IQueuePluginMetadata
{
QueueProviderType QueueType { get; }
}
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class QueueTypeAttribute : ExportAttribute, IQueuePluginMetadata
{
public QueueTypeAttribute(QueueProviderType QueueType)
: base(typeof(IQueueProviderPlugin<>))
{
this.QueueType = QueueType;
}
public QueueProviderType QueueType { get; private set; }
}
[QueueTypeAttribute(QueueProviderType.InProcess)] // : ExportAttribute !!!
[Export(typeof(IQueueProviderPlugin<>))] // duplicate export
public class InProcessQueuePlugin : IQueueProviderPlugin<string>
{
private Queue<string> _queue = new Queue<string>();
public string Dequeue()
{
return _queue.Dequeue();
}
public void Enqueue(string item)
{
_queue.Enqueue(item);
}
}
}
答案 0 :(得分:0)
查看可能的解决方案 https://social.msdn.microsoft.com/Forums/vstudio/en-US/02a2a0b9-0c3e-4ba1-a525-ffa3a140bae9/why-mef-does-not-discover-my-exports?forum=csharpgeneral 如果您有更好的MEF Vs解决方案,请更新。泛型问题。 问候, 原子
答案 1 :(得分:0)
当您的对象实际上未通过该导出关闭时,您正在尝试导出一个打开的泛型类型。要导出IQueueProviderPlugin<string>
,请使用[Export(typeof(IQueueProviderPlugin<string>))]
而不是[Export(typeof(IQueueProviderPlugin<>))]
。
如果您想导出IQueueProviderPlugin<>
,则必须将导出设置为开放(未封闭)通用类型:
[QueueTypeAttribute(QueueProviderType.InProcess)] // exports IQueueProviderPlugin<>
public class InProcessQueuePlugin<T> : IQueueProviderPlugin<T>
{
readonly Queue<T> _queue = new Queue<T>();
public T Dequeue() => _queue.Dequeue();
public void Enqueue(T item)
{
_queue.Enqueue(item);
}
}