1

У меня самое сложное время выяснить, как зарегистрировать пользовательский ISiteMapNodeVisibilityProvider (SiteMapNodeVisibilityProviderBase), используя Autofac в MvcSiteMapProvider.MvcSiteMapProvider + Autofac + ISiteMapNodeVisibilityProvider из другой сборки

Все работает нормально до тех пор, пока я не переместил поставщика видимости на другую сборку. Теперь, независимо от того, что я пытаюсь, я всегда получаю

Экземпляр поставщика видимости с именем «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 OR MvcSiteMap, но, как я уже сказал, все работает нормально, пока я не переместил поставщика видимости на другую сборку.

Большое спасибо за ваше время и внимание! Я расстроен в этот момент.

ответ

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" }; 
+0

Я чувствую себя таким балбес .. Пространство имен для MyWasWorkingVisibilityProvider (имена и место вовлеченных были изменены, чтобы защищен невиновным) EVER изменило чуть-чуть .. Одна из тех вещей, что заставляет вас столкнуться с ладонью. Рад узнать, что я понял это правильно, но то, что помогло мне разобраться в этом, - это ваше упоминание о RegisterAllImplementationsOfInterface .. это показалось важным, поэтому я углубился в глубь, увидел, что он нашел поставщика видимости и скопировал/вставить то, что он нашел, с чем Я настроил .. бок о бок .. и БАМ .. ударил меня между глазами. Так что спасибо! Извините, что беспокою вас об этом. –