[英]Why MEF does not discover my generic exports?
我想使用MEF使用隊列插件。 我嘗試了以下操作,但是以下使用Import屬性(在下面的示例中)修飾的queuePlugins和AlternativeApproach字段為空知道嗎? 謝謝,ATom
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);
}
}
}
在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有更好的解決方案,請進行更新。 泛型問題。 問候,ATom
當您的對象實際上未通過該導出關閉時,您正在嘗試導出打開的泛型類型。 要導出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);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.