好吧,我很确定这是非常明显的事情,但我没有找到它。
我正在尝试根据元数据从 MEF 容器中导出对象。
我在像这样的教程中看到过这样做:
但是,我的导出没有此工作所需的元数据属性。那里可能有什么问题?
[Export(typeof(IController))]
[ExportMetadata("controllerName","Home")]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class HomeController : Controller{}
再一次
public class MyControllerFactory : IControllerFactory
{
private readonly CompositionContainer _container;
public MyControllerFactory(CompositionContainer container)
{
_container = container;
}
public IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName)
{
var controllerExport = _container.GetExports<IController>().
Where(exp => exp.Metadata) //Here it doesn't have the Metadata property.
}
}
我知道 GetExports 返回一个 Lazy 集合,它当然没有 Metadata 属性,但在我浏览的大多数教程中都假定它。
如何正确执行此操作?
编辑
这是我做的:
public interface IControllerMetaData
{
string Name { get; }
string Subdomain { get; }
}
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple=false)]
public class ControllerMetadataAttribute : ExportAttribute
{
public ControllerMetadataAttribute(string name, string subdomain)
: base(typeof(IControllerMetaData))
{
Name = name;
Subdomain = subdomain;
}
public string Name { get; set; }
public string Subdomain { get; set; }
}
然后在每个 Controller 中
[Export(typeof(IController))]
[ControllerMetadata("Home", "")]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class HomeController : SubdomainManagedController
在工厂里
var controllerExport = _container.GetExports<IController, ControllerMetadataAttribute>().
Where(exp => exp.Metadata.Name.Equals(controllerName) && exp.Metadata.Subdomain.Equals(subdomain)).
FirstOrDefault();
我得到了
提供的类型“ControllerMetadataAttribute”不是有效的元数据 View 。`
怎么就无效了。它有 MetaDataAttribute 和所有吗?
最佳答案
在您的示例中,您使用的是 GetExports<T>
, 而不是 GetExports<T,TMetadata>
.在一个简单的示例中,您可以使用 GetExports<IController, IDictionary<string, object>>
,这将允许您查询,但更好的方法是创建自定义元数据协定:
public interface INameMetadata
{
string Name { get; }
}
然后您可以将其用作:
[Export(typeof(IController))]
[ExportMetadata("Name", "Home")]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class HomeController : Controller { }
然后将您的导入更改为:
var controller = _container.GetExports<IController, INameMetadata>()
.Where(e => e.Metadata.Name.Equals(controllerName))
.Select(e => e.Value)
.FirstOrDefault();
更进一步,您可以结合您的 Export
和 ExportMetadata
属性合并为单个属性:
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false), MetadataAttribute]
public class ExportControllerAttribute : ExportAttribute, INameMetadata
{
public ExportControllerAttribute(string name)
: base(typeof(IController))
{
Name = name;
}
public string Name { get; private set; }
}
现在,您可以将其用于导出:
[ExportController("Home"), PartCreationPolicy(CreationPolicy.NonShared)]
public class HomeController : Controller { }
关于c# - MEF和基于元数据的导出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7662629/