MvcSiteMapProvider:如何加载额外的web从MVC 4中启用mef的模块中获取站点地图文件

本文关键字:启用 MVC mef 模块 文件 地图 站点 获取 web 何加载 加载 | 更新日期: 2023-09-27 18:12:47

我在c#类库项目中有一个单独的模块,它是通过MEF导入加载的。作为将站点地图信息与模块一起引入的初步尝试,我添加了一个web。网站地图文件与必要的标记,但我似乎不能得到一个清楚的感觉如何加载它,并将其附加到主机MVC项目网站地图在内存。

我也尝试使用MvcSiteMapNode属性,但还没有真正能够得到这个工作。

首先,属性和SiteMap哪个方法最容易使用?

其次,谁能告诉我如何做这两件事?

我有一个偏好使用站点地图文件,因为它应该避免依赖于MvcSiteMapProvider在MEF模块

MvcSiteMapProvider:如何加载额外的web从MVC 4中启用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>();

当然,如果您有多个文件,则需要多次注册IXmlSourceXmlSiteMapNodeProviderXmlSiteMapNodeProvider只具有合并根节点下的节点的能力,因此您不能将它们放置在SiteMap中的任何位置。

XML和Attributes是配置MvcSiteMapProvider最不灵活的选项。

<标题> 的另一种方法

最灵活的选择是使用ISiteMapNodeProvider实现来加载配置数据,这也需要一个外部DI容器。第二个最佳选择是使用动态节点提供程序实现,但其限制是它们不能包含根节点,并且需要XML节点或. net属性来承载提供程序。

然而,如果你不想要任何第三方依赖,你将需要一个自定义抽象(DTO),它定义在你自己的基库中,通过MEF导出,然后由ISiteMapNodeProviderIDynamicNodeProvider使用从抽象中加载数据。

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 (ISiteMapNodeToParentRelationDynamicNode)所期望的类型。

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,这样你就可以用代码来表达节点。请看下面的拉取请求: