1

对于 MvcSiteMapProvider v4,我通过重写 SiteMapNodeUrlResolverBase 编写了一个自定义站点地图 url 解析器。但我不知道如何在 MvcSiteMapProviderRegistry 中注册它以确保始终使用我自己的 SiteMapNodeUrlResolver 解析节点的 Url。

我期待的是:

this.For<ISiteMapNodeUrlResolver>().Use<MyUrlResolver>();

但这不起作用,我该怎么做?

4

1 回答 1

0

SiteMapNodeUrlResolvers(以及可见性提供程序和动态节点提供程序)使用策略模式,因此您可以连接多个实例,然后按名称引用每个实例。然后该方法使用该名称AppliesTo()来确定每个节点使用哪个 URL 解析器。

如果您从 SiteMapNodeUrlResolverBase 继承而不是实现 ISiteMapNodeUrlResolver,则默认实现AppliesTo()在大多数情况下都可以工作。然后,此行(默认情况下已包含在模块中)将自动连接所有 SiteMapNodeUrlResolvers:

// Multiple implementations of strategy based extension points
CommonConventions.RegisterAllImplementationsOfInterface(
    (interfaceType, implementationType) => this.For(interfaceType).Singleton().Use(implementationType),
    multipleImplementationTypes,
    allAssemblies,
    excludeTypes,
    "^Composite");

默认情况下,它只扫描 MvcSiteMapProvider.dll 和您的 MVC 项目。如果您在单独的程序集中定义了 URL 解析器,则需要修改 allAssemblies 变量以确保它包含您的自定义程序集。

加载后,您需要按名称调用它。默认实现使用“ShortAssemblyQualifiedName”,它与您通常用来引用配置文件中的类型的字符串相同(只要您的程序集不是强命名的)。

<mvcSiteMapNode title="Home" action="Index" controller="Home" urlResolver="MyNamespace.MySiteMapNodeUrlResolver, MyAssembly" />

urlResolver 属性/属性必须在您希望覆盖默认实现的每个节点上设置。

如果您愿意,您可以自己实现AppliesTo() 方法,这样您就可以减少所需的配置量。请注意,这仅在使用外部 DI 容器时有效,因为内部 DI 容器使用配置中的类型名称来实例化对象。

public override bool AppliesTo(string providerName)
{
    return "myUrlResolver".Equals(providerName, StringComparison.InvariantCulture);
}

<mvcSiteMapNode title="Home" action="Index" controller="Home" urlResolver="myUrlResolver" />
于 2013-10-15T10:38:38.833 回答