【问题标题】:MvcSiteMapProvider + Autofac + ISiteMapNodeVisibilityProvider from another assembly来自另一个程序集的 MvcSiteMapProvider + Autofac + ISiteMapNodeVisibilityProvider
【发布时间】:2014-12-11 16:54:35
【问题描述】:

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

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

找不到名为“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 提供程序的向导,但是,就像我说的,在我将可见性提供程序移动到另一个程序集之前,一切正常。

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

【问题讨论】:

    标签: asp.net-mvc autofac mvcsitemapprovider asp.net-mvc-sitemap


    【解决方案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 属性/属性的节点配置不正确。

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

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

    【讨论】:

    • 我觉得自己像个笨蛋。。MyWasWorkingVisibilityProvider 的命名空间(相关人员的姓名和地点已更改以保护无辜者)变化如此之小。其中一件让你面对的事情棕榈。很高兴知道我做对了,但帮助我弄清楚的是您提到 RegisterAllImplementationsOfInterface .. 这似乎很重要,所以我深入挖掘,发现它正在寻找可见性提供程序,并复制/粘贴它找到的内容我已经配置了..并排..和 BAM.. 打在我的眼睛之间。那谢谢啦!很抱歉给您带来麻烦。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多