1

我很难弄清楚如何在 MvcSiteMapProvider 中使用 Autofac 注册自定义 ISiteMapNodeVisibilityProvider (SiteMapNodeVisibilityProviderBase)。

在我将可见性提供程序移至另一个程序集之前,一切都运行良好。现在,无论我尝试什么,我总是得到

找不到名为“MyWasWorkingVisibilityProvider, MyNewAssembly”的可见性提供程序实例。检查您的 DI 配置以确保具有此名称的可见性提供程序实例存在并且配置正确。

根据MvcSiteMapProvider文档和代码,看来我需要以某种方式进入SiteMapNodeVisibilityProviderStrategy......我想我已经在下面做到了......但我不是 Autofac 忍者。

MvcSiteMapProviderModule.cs,我在任何我能想到的地方都添加了新的程序集......

string[] includeAssembliesForScan = new string[] { "MyOldAssembly", "MyNewAssembly" };

var allAssemblies = new Assembly[] { currentAssembly, siteMapProviderAssembly, typeof(MyWasWorkingVisibilityProvider).Assembly };

builder.RegisterType<SiteMapNodeVisibilityProviderStrategy>()
    .As<ISiteMapNodeVisibilityProviderStrategy>()
    .WithParameters(new List<Parameter> { new NamedParameter("defaultProviderName", string.Empty), new NamedParameter("siteMapNodeVisibilityProviders", new [] { new MyWasWorkingVisibilityProvider() }) });


builder.RegisterType<MyWasWorkingVisibilityProvider>()
    .As<ISiteMapNodeVisibilityProvider>();

但它仍然不起作用。

值得一提的是,任何特定菜单项的可见性提供程序都在数据库中进行了配置,并且整个菜单结构都加载了一个动态节点提供程序,该提供程序现在也位于与我移动可见性提供程序的位置相同的程序集中。动态节点提供程序显然正在工作,因为它一直到尝试加载可见性提供程序的地步。

我认为https://github.com/maartenba/MvcSiteMapProvider/issues/237看起来很有帮助,我无法编译可见性提供程序特定的代码..

另一个没有任何效果的例子:MVC Site Map Provider - SiteMapPath Performance Very Slow?

所以我现在被困住了。我不是 Autofac 或 MvcSiteMap 提供程序的向导,但是,就像我说的,在我将可见性提供程序移动到另一个程序集之前,一切正常。

非常感谢您的时间和关注!在这一点上我很沮丧。

4

1 回答 1

1

只是一种预感,但我怀疑您没有visibilityProvider="MyNamespace.MyVisibilityProvider, MyAssembly"将配置中的所有引用更新到新程序集。SiteMapNodeVisibilityProviderBase 使用 .NET 完整类型名称来定位正确的类型,包括程序集名称。

// From MvcSiteMapProvider.SiteMapNodeVisibilityProviderBase 
public virtual bool AppliesTo(string providerName)
{
    if (string.IsNullOrEmpty(providerName))
        return false;

    return this.GetType().Equals(Type.GetType(providerName, false));
}

至于 DI 注册,如果您将第一次调用留CommonConventions.RegisterAllImplementationsOfInterface()在原地,那么您就可以使用以下行:

var allAssemblies = new Assembly[] { currentAssembly, siteMapProviderAssembly, typeof(MyWasWorkingVisibilityProvider).Assembly };

所以代码应该是这样的:

var allAssemblies = new Assembly[] { currentAssembly, siteMapProviderAssembly, typeof(MyWasWorkingVisibilityProvider).Assembly };
var excludeTypes = new Type[] { 
    // Use this array to add types you wish to explicitly exclude from convention-based  
    // auto-registration. By default all types that either match I[TypeName] = [TypeName] or 
    // I[TypeName] = [TypeName]Adapter will be automatically wired up as long as they don't 
    // have the [ExcludeFromAutoRegistrationAttribute].
    //
    // If you want to override a type that follows the convention, you should add the name 
    // of either the implementation name or the interface that it inherits to this list and 
    // add your manual registration code below. This will prevent duplicate registrations 
    // of the types from occurring. 

    // Example:
    // typeof(SiteMap),
    // typeof(SiteMapNodeVisibilityProviderStrategy)
};
var multipleImplementationTypes = new Type[]  { 
    typeof(ISiteMapNodeUrlResolver), 
    typeof(ISiteMapNodeVisibilityProvider), 
    typeof(IDynamicNodeProvider) 
};

// Matching type name (I[TypeName] = [TypeName]) or matching type name + suffix Adapter (I[TypeName] = [TypeName]Adapter)
// and not decorated with the [ExcludeFromAutoRegistrationAttribute].
CommonConventions.RegisterDefaultConventions(
    (interfaceType, implementationType) => builder.RegisterType(implementationType).As(interfaceType).SingleInstance(),
    new Assembly[] { siteMapProviderAssembly },
    allAssemblies,
    excludeTypes,
    string.Empty);

// Multiple implementations of strategy based extension points (and not decorated with [ExcludeFromAutoRegistrationAttribute]).
CommonConventions.RegisterAllImplementationsOfInterface(
    (interfaceType, implementationType) => builder.RegisterType(implementationType).As(interfaceType).SingleInstance(),
    multipleImplementationTypes,
    allAssemblies,
    excludeTypes,
    string.Empty);

// Registration of internal controllers
CommonConventions.RegisterAllImplementationsOfInterface(
    (interfaceType, implementationType) => builder.RegisterType(implementationType).As(interfaceType).AsSelf().InstancePerDependency(),
    new Type[] { typeof(IController) },
    new Assembly[] { siteMapProviderAssembly },
    new Type[0],
    string.Empty);

因此,简而言之,您的 DI 配置是正确的,但您的 VisibilityProvider 属性/属性的节点配置不正确。

注意:以下行仅用于扫描控制器上的 [MvcSiteMapNode] 属性,这些控制器可能与 MvcSiteMapProvider 不在同一个项目中,与可见性提供程序的设置无关。

string[] includeAssembliesForScan = new string[] { "MyOldAssembly", "MyNewAssembly" };
于 2014-12-12T06:48:26.807 回答