MvcSiteMapProvider + Autofac + ISiteMapNodeVisibilityProvider из другой сборки

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

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

Экземпляр поставщика видимости с именем "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 - производительность SiteMapPath очень низкая?

Так что я застрял сейчас. Я не волшебник с поставщиком Autofac ИЛИ 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" };
Другие вопросы по тегам