MvcSiteMapProvider:如何加载额外的web从MVC 4中启用mef的模块中获取站点地图文件
本文关键字:启用 MVC mef 模块 文件 地图 站点 获取 web 何加载 加载 | 更新日期: 2023-09-27 18:12:47
我在c#类库项目中有一个单独的模块,它是通过MEF导入加载的。作为将站点地图信息与模块一起引入的初步尝试,我添加了一个web。网站地图文件与必要的标记,但我似乎不能得到一个清楚的感觉如何加载它,并将其附加到主机MVC项目网站地图在内存。
我也尝试使用MvcSiteMapNode属性,但还没有真正能够得到这个工作。
首先,属性和SiteMap哪个方法最容易使用?
其次,谁能告诉我如何做这两件事?
我有一个偏好使用站点地图文件,因为它应该避免依赖于MvcSiteMapProvider在MEF模块
您可以将XML嵌入到模块中,然后以某种方式通过MEF导出它们,我很确定这是一个选项。
要从内存加载XML,您需要使用外部DI容器并自己实现IXmlSource
接口。
public class MyXmlSource : IXmlSource
{
public XDocument GetXml()
{
// Load the XML from wherever...
}
}
那么DI配置只需要换出默认的XmlSource
。
var excludeTypes = new Type[] {
typeof(IXmlSource)
};
// More DI config not shown...
this.For<IXmlSource>()
.Use<MyXmlSource>();
当然,如果您有多个文件,则需要多次注册IXmlSource
和XmlSiteMapNodeProvider
。XmlSiteMapNodeProvider
只具有合并根节点下的节点的能力,因此您不能将它们放置在SiteMap中的任何位置。
XML和Attributes是配置MvcSiteMapProvider
最不灵活的选项。
最灵活的选择是使用ISiteMapNodeProvider
实现来加载配置数据,这也需要一个外部DI容器。第二个最佳选择是使用动态节点提供程序实现,但其限制是它们不能包含根节点,并且需要XML节点或. net属性来承载提供程序。
然而,如果你不想要任何第三方依赖,你将需要一个自定义抽象(DTO),它定义在你自己的基库中,通过MEF导出,然后由ISiteMapNodeProvider
或IDynamicNodeProvider
使用从抽象中加载数据。
public class SiteMapNodeDto
{
public string Key { get; set; }
public string ParentKey { get; set; }
public string Title { get; set; }
public IDictionary<string, object> RouteValues { get; set; }
// Additional properties...
}
然后有一个接口,你的模块可以实现提供节点。
public interface IModuleSiteMapNodeProvider
{
IEnumerable<SiteMapNodeDto> GetNodes();
}
我使用MEF的简短经验是几年前的事了,所以我不记得如何导出一个类型并将其导入到其他地方,所以您需要自己解决这个问题。
然后在主应用程序中,您可以创建一个方法,用于将DTO转换为MvcSiteMapProvider
(ISiteMapNodeToParentRelation
或DynamicNode
)所期望的类型。
public static SiteMapNodeProviderExtensions
{
public static ISiteMapToParentRelation CreateNode(this ISiteMapNodeHelper helper, SiteMapNodeDto dto, string sourceName)
{
string key = helper.CreateNodeKey(
dto.ParentKey,
dto.Key,
dto.Url,
dto.Title,
dto.Area,
dto.Controller,
dto.Action,
dto.HttpMethod,
dto.Clickable);
var nodeParentMap = helper.CreateNode(key, attribute.ParentKey, sourceName);
var node = nodeParentMap.Node;
node.Title = title;
// Populate remaining properties...
return nodeParentMap;
}
}
然后在ISiteMapNodeProvider
中,您只需要为每个节点调用此方法。
public IEnumerable<ISiteMapNodeToParentRelation> GetSiteMapNodes(ISiteMapNodeHelper helper)
{
string sourceName = typeof(SiteMapNodeDto).Name;
IEnumerable<SiteMapNodeDto> dtos = someExternalSource.GetNodes();
foreach (var dto in dtos)
{
yield return helper.CreateNode(dto, sourceName);
}
}
如果你想让提供SiteMap节点成为模块开发人员的头等特性(并且让节点的层次结构像XML那样容易理解),你可以创建一个Fluent API,这样你就可以用代码来表达节点。请看下面的拉取请求:
标题>