【发布时间】:2014-09-21 02:55:57
【问题描述】:
我一直在研究StockTrader RI for PRISM 的内部工作原理。
在此 RI 中,MEF 和自定义属性系统结合使用以向区域注册视图,而不是在 Module Initializer 中将事物连接到 RegionManager。
更具体地说,有一个ViewExportAttribute 实现:
MetaDataAttributeIViewRegionRegistration
System.Lazy<T,TMetaData> 在AutoPopulateExportedViewsBehavior 中可以利用 MetaDataAttribute 和“属性视图”IViewRegionRegistration 来实现区域和视图的正确链接。
一般System.Lazy<T,TMetaData> 和实际元数据之间的相互作用在here 中进行了详细说明,更具体地说是“使用强类型元数据”部分。
明确地说,我理解 Lazy 的意图,它显然有效。但是,我完全不明白的是属性提供的元数据视图(它只是一个接口)和用 MetaDataAttribute 提供的实际数据填充 TMetaData 属性之间的链接发生位置和方式 .
为了让我的要求更清楚,来自previously referenced example:
首先,定义一个接口,它可以作为一种模板来传递某些元数据:
public interface IMessageSenderCapabilities
{
MessageTransport Transport { get; }
bool IsSecure { get; }
}
接下来,定义一个对应的MetaDataAttribute(与上一个接口的属性相同)
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple=false)]
public class MessageSenderAttribute : ExportAttribute
{
public MessageSenderAttribute() : base(typeof(IMessageSender)) { }
public MessageTransport Transport { get; set; }
public bool IsSecure { get; set; }
}
该属性可用于导出,其中为属性属性设置实际值:
[MessageSender(Transport=MessageTransport.Smtp, IsSecure=true)]
public class SecureEmailSender : IMessageSender
{
public void Send(string message)
{
Console.WriteLine(message);
}
}
现在终于可以进行一些导入了:
public class HttpServerHealthMonitor
{
[ImportMany]
public Lazy<IMessageSender, IMessageSenderCapabilities>[] Senders { get; set; }
public void SendNotification()
{
foreach(var sender in Senders)
{
if (sender.Metadata.Transport == MessageTransport.Smtp &&
sender.Metadata.IsSecure)
{
var messageSender = sender.Value;
messageSender.Send("Server is fine");
break;
}
}
}
}
在这最后一步中:sender.Metadata.Transport 在那个非常 Lazy 上进行评估。因此,在此过程中,Lazy 会意识到元数据的实际值,而不仅仅是它传递的接口。 我想了解这是如何发生的,谁或什么要对此负责。即使它只是一个非常一般的流程。
【问题讨论】: