.NET中仅使用MEF获得必要的插件
|
我有IMessageSender接口。
using System.ComponentModel.Composition;
public interface IMessageSender
{
void Send(string message);
}
我有两个实现此接口的插件。这是plugin.cs。
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Reflection;
using System;
[Export(typeof(IMessageSender))]
public class EmailSender : IMessageSender
{
public void Send(string message)
{
Console.WriteLine(message);
}
}
这是plugin2.cs
[Export(typeof(IMessageSender))]
public class EmailSender : IMessageSender
{
public void Send(string message)
{
Console.WriteLine(message + \"!!!!\");
}
}
我有这段代码可以通过MEF运行这些插件。
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Reflection;
using System.Collections.Generic;
using System;
public class Program
{
[ImportMany]
public IEnumerable<IMessageSender> MessageSender { get; set; }
public static void Main(string[] args)
{
Program p = new Program();
p.Run();
foreach (var message in p.MessageSender) {
message.Send(\"hello, world\");
}
}
public void Run()
{
Compose();
}
private void Compose()
{
var catalog = new AggregateCatalog();
catalog.Catalogs.Add(new DirectoryCatalog(@\"./\"));
var container = new CompositionContainer(catalog);
container.ComposeParts(this);
}
}
编译后,我得到了想要的东西。
> mono program.exe
hello, world
hello, world!!!!
我的问题是如何有选择地用尽许多插件。本示例仅获取所有可用的插件来运行所有插件,但是当我只想运行第一个插件或第二个插件时该怎么办?
例如,可以仅按以下方式运行plugin2.dll吗?
public static void Main(string[] args)
{
Program p = new Program();
p.Run();
var message = messageSender.GetPlugin(\"plugin\"); // ???
message.Send(\"hello, world\");
}
解决了
基于该站点以及Matthew Abbott的回答。我可以拿出这个工作代码。
接口代码(interface.cs)
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Reflection;
using System;
public interface IMessageSender
{
void Send(string message);
}
public interface IMessageSenderMetadata
{
string Name {get; }
string Version {get; }
}
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class MessageMetadataAttribute : ExportAttribute, IMessageSenderMetadata
{
public MessageMetadataAttribute( string name, string version)
: base(typeof(IMessageSender))
{
Name = name;
Version = version;
}
public string Name { get; set; }
public string Version { get; set; }
}
插件代码(Plugin.cs ...)
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Reflection;
using System;
[MessageMetadataAttribute(\"EmailSender1\", \"1.0.0.0\")]
public class EmailSender : IMessageSender
{
public void Send(string message)
{
Console.WriteLine(message + \"????\");
}
}
Program.cs
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Reflection;
using System.Collections.Generic;
using System;
using System.Linq;
public class Program
{
[ImportMany(typeof(IMessageSender), AllowRecomposition = true)]
public IEnumerable<Lazy<IMessageSender, IMessageSenderMetadata>> Senders { get; set; }
public static void Main(string[] args)
{
Program p = new Program();
p.Run();
var sender1 = p.GetMessageSender(\"EmailSender1\",\"1.0.0.0\");
sender1.Send(\"hello, world\");
sender1 = p.GetMessageSender(\"EmailSender2\",\"1.0.0.0\");
sender1.Send(\"hello, world\");
}
public void Run()
{
Compose();
}
public IMessageSender GetMessageSender(string name, string version)
{
return Senders
.Where(l => l.Metadata.Name.Equals(name) && l.Metadata.Version.Equals(version))
.Select(l => l.Value)
.FirstOrDefault();
}
private void Compose()
{
var catalog = new AggregateCatalog();
catalog.Catalogs.Add(new DirectoryCatalog(@\"./\"));
var container = new CompositionContainer(catalog);
container.ComposeParts(this);
}
}
没有找到相关结果
已邀请:
1 个回复
期差骇蓟
然后,您需要做的是确保为需要导出的每个导出分配该元数据:
MEF要做的是,使用存储在
属性中的值,生成一个实现接口interface11ѭ的项目。 完成此操作后,您可以进行一些过滤,因此将
重新定义为以下内容:
MEF将创建一个ѭ15个实例的枚举,这些实例支持实例类型的延迟实例化。我们可以查询为:
使用
参数的
参数运行此命令将导致返回our19ѭ实例。需要注意的重要一点是,我们基于查询与类型关联的元数据的方式,选择了要使用的特定实例。 您可以再进一步,可以将
和
属性合并为一个属性,例如:
这使我们可以使用单个属性来导出类型,同时仍提供其他元数据:
显然,以这种方式查询将为您提供设计决策。使用
实例意味着您将能够推迟实例的实例化,但这确实意味着每个惰性实例只能创建一个实例。 MEF框架的Silverlight变体还支持
类型,它允许您每次启动
的新实例,而列表仍然为您提供丰富的元数据机制。