Jak zaimplementować niestandardowy SiteMapNodeProvider

Usiłuję zaadaptować MvcSiteMapProvider, aby utworzyć ścieżkę nawigacyjną na podstawie niektórych informacji przechowywanych w bazie danych.

Odpowiedź wto post brzmiał obiecująco, więc zaimplementowałem mój własny SiteMapNodeProvider. Ale wtedy nie wiedziałem, jak to wszystko uporządkować, więc nowo zaimplementowany SiteMapNodeProvider jest używany zamiast statycznego pliku xml („Mvc.sitemap”).

Gdy używam SimpleInjector w moim projekcie, wywołałem metodę instalacji w moim już istniejącym kodzie Injection-initialization.

 public static void Initialize()
    {
        Injection.Global = new Container();
        InitializeContainer(Injection.Global);
        Injection.Global.RegisterMvcControllers(Assembly.GetExecutingAssembly());
        Injection.Global.RegisterMvcAttributeFilterProvider();
        Injection.Global.Verify();
        DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(Injection.Global));
    }

    private static void InitializeContainer(Container container)
    {
        // Setup configuration of DI
        MvcSiteMapProviderContainerInitializer.SetUp(container);

        //... register some other stuff for my project here ...
    }

Klasa MvcSiteMapProviderContainerInitializer została utworzona przez pakiet: „Mvcsitemapprovider.mvc4.di.simpleinjector / 4.4.5”

Czy ktoś wie, co zrobić, aby mój projekt używał nowo utworzonego SiteMapNodeProvider? Nie mogłem znaleźć żadnej dokumentacji na ten temat w oficjalnym dokumencie ...

edytować: Próbowałem tego, co zasugerowałeś (nawet usunąłem stare rzeczy DI i użyłem tylko tego z pakietu nuget), ale wciąż otrzymuję błędy ... oto co mam w moim MvcSiteMapProviderContainerInitializer

    public static void SetUp(Container container)
        {
            bool securityTrimmingEnabled = false;
            bool enableLocalization = true;
            string absoluteFileName = HostingEnvironment.MapPath("~/Mvc.sitemap");
            TimeSpan absoluteCacheExpiration = TimeSpan.FromMinutes(5);
            string[] includeAssembliesForScan = new string[] { "testsitemap" };

// Extension to allow resolution of arrays by GetAllInstances (natively based on IEnumerable).
// source from: https://simpleinjector.codeplex.com/wikipage?title=CollectionRegistrationExtensions
            AllowToResolveArraysAndLists(container);

            var currentAssembly = typeof(MvcSiteMapProviderContainerInitializer).Assembly;
            var siteMapProviderAssembly = typeof(SiteMaps).Assembly;
            var allAssemblies = new Assembly[] { currentAssembly, siteMapProviderAssembly };
            var excludeTypes = new Type[]
                {
                    typeof (SiteMapNodeVisibilityProviderStrategy),
                    typeof (SiteMapXmlReservedAttributeNameProvider),
                    typeof (SiteMapBuilderSetStrategy),
                    typeof (ControllerTypeResolverFactory),

// Added 2013-06-28 by eric-b to avoid default singleton registration:
                    typeof(XmlSiteMapController),

// Added 2013-06-28 by eric-b for SimpleInjector.Verify method:
                    typeof(PreservedRouteParameterCollection),
                    typeof(MvcResolver),
                    typeof(MvcSiteMapProvider.SiteMap),
                    typeof(MetaRobotsValueCollection),
                    typeof(RoleCollection),
                    typeof(SiteMapPluginProvider),
                    typeof(ControllerTypeResolver),
                    typeof(RouteValueDictionary),
                    typeof(AttributeDictionary)

                    ,typeof(SiteMapNodeCreator)
                };
            var multipleImplementationTypes = new Type[]
                {
                    typeof (ISiteMapNodeUrlResolver),
                    typeof (ISiteMapNodeVisibilityProvider),
                    typeof (IDynamicNodeProvider)
                };

// Single implementations of interface with matching name (minus the "I").
            CommonConventions.RegisterDefaultConventions(
                (interfaceType, implementationType) => container.RegisterSingle(interfaceType, implementationType),
                new Assembly[] { siteMapProviderAssembly },
                allAssemblies,
                excludeTypes,
                string.Empty);

// Multiple implementations of strategy based extension points
            CommonConventions.RegisterAllImplementationsOfInterfaceSingle(
                (interfaceType, implementationTypes) => container.RegisterAll(interfaceType, implementationTypes),
                multipleImplementationTypes,
                allAssemblies,
                new Type[0],
                "^Composite");

            container.Register<XmlSiteMapController>();

// Visibility Providers
            container.RegisterSingle<ISiteMapNodeVisibilityProviderStrategy>(() =>
                                                                       new SiteMapNodeVisibilityProviderStrategy(
                                                                           container.GetAllInstances
                                                                               <ISiteMapNodeVisibilityProvider>().
                                                                               ToArray(), string.Empty));

// Pass in the global controllerBuilder reference
            container.RegisterSingle<ControllerBuilder>(() => ControllerBuilder.Current);

            container.RegisterSingle<IControllerBuilder, ControllerBuilderAdaptor>();

            container.RegisterSingle<IBuildManager, BuildManagerAdaptor>();

            container.RegisterSingle<IControllerTypeResolverFactory>(() =>
                                                               new ControllerTypeResolverFactory(new string[0],
                                                                                                 container.GetInstance
                                                                                                     <IControllerBuilder
                                                                                                     >(),
                                                                                                 container.GetInstance
                                                                                                     <IBuildManager>()));

// Configure Security
            container.RegisterAll<IAclModule>(typeof(AuthorizeAttributeAclModule), typeof(XmlRolesAclModule));
            container.RegisterSingle<IAclModule>(() => new CompositeAclModule(container.GetAllInstances<IAclModule>().ToArray()));

// Setup cache




            container.RegisterSingle<System.Runtime.Caching.ObjectCache>(() => System.Runtime.Caching.MemoryCache.Default);
            container.RegisterSingleOpenGeneric(typeof(ICacheProvider<>), typeof(RuntimeCacheProvider<>));
            container.RegisterSingle<ICacheDependency>(() => new RuntimeFileCacheDependency(absoluteFileName));

            container.RegisterSingle<ICacheDetails>(() => new CacheDetails(absoluteCacheExpiration, TimeSpan.MinValue, container.GetInstance<ICacheDependency>()));

// Configure the visitors
            container.RegisterSingle<ISiteMapNodeVisitor, UrlResolvingSiteMapNodeVisitor>();


// Prepare for the sitemap node providers
            container.RegisterSingle<ISiteMapXmlReservedAttributeNameProvider>(
                () => new SiteMapXmlReservedAttributeNameProvider(new string[0]));

            container.RegisterSingle<IXmlSource>(() => new FileXmlSource(absoluteFileName));


            // Register the sitemap node providers
            container.RegisterSingle<XmlSiteMapNodeProvider>(() => container.GetInstance<XmlSiteMapNodeProviderFactory>()
                .Create(container.GetInstance<IXmlSource>()));
            container.RegisterSingle<ReflectionSiteMapNodeProvider>(() => container.GetInstance<ReflectionSiteMapNodeProviderFactory>()
                .Create(includeAssembliesForScan));

            // Register your custom sitemap node provider
            container.RegisterSingle<ISiteMapNodeProvider, CustomSiteMapNodeProvider>();

            // Register the collection of sitemap node providers (including the custom one)
            container.RegisterSingle<ISiteMapBuilder>(() => container.GetInstance<SiteMapBuilderFactory>()
                .Create(new CompositeSiteMapNodeProvider(
                    container.GetInstance<XmlSiteMapNodeProvider>(),
                    container.GetInstance<ReflectionSiteMapNodeProvider>(),
                    container.GetInstance<CustomSiteMapNodeProvider>())));


            container.RegisterAll<ISiteMapBuilderSet>(ResolveISiteMapBuilderSets(container, securityTrimmingEnabled, enableLocalization));
            container.RegisterSingle<ISiteMapBuilderSetStrategy>(() => new SiteMapBuilderSetStrategy(container.GetAllInstances<ISiteMapBuilderSet>().ToArray()));
        }

        private static IEnumerable<ISiteMapBuilderSet> ResolveISiteMapBuilderSets(Container container, bool securityTrimmingEnabled, bool enableLocalization)
        {
            yield return new SiteMapBuilderSet(
                "default",
                securityTrimmingEnabled,
                enableLocalization,
                container.GetInstance<ISiteMapBuilder>(),
                container.GetInstance<ICacheDetails>());
        }

        private static void AllowToResolveArraysAndLists(Container container)
        {
            container.ResolveUnregisteredType += (sender, e) =>
            {
                var serviceType = e.UnregisteredServiceType;

                if (serviceType.IsArray)
                {
                    RegisterArrayResolver(e, container,
                        serviceType.GetElementType());
                }
                else if (serviceType.IsGenericType &&
                    serviceType.GetGenericTypeDefinition() == typeof(IList<>))
                {
                    RegisterArrayResolver(e, container,
                        serviceType.GetGenericArguments()[0]);
                }
            };
        }

        private static void RegisterArrayResolver(UnregisteredTypeEventArgs e, Container container, Type elementType)
        {
            var producer = container.GetRegistration(typeof(IEnumerable<>)
                .MakeGenericType(elementType));
            var enumerableExpression = producer.BuildExpression();
            var arrayMethod = typeof(Enumerable).GetMethod("ToArray")
                .MakeGenericMethod(elementType);
            var arrayExpression = Expression.Call(arrayMethod, enumerableExpression);
            e.Register(arrayExpression);
        }
    }

ale wciąż mam następujący wyjątek:

Nie znaleziono rejestracji dla typu DynamicSiteMapNodeBuilder i nie można dokonać niejawnej rejestracji. Konstruktor typu DynamicSiteMapNodeBuilder zawiera parametr typu ISiteMapNodeCreator o nazwie „siteMapNodeCreator”, który nie jest zarejestrowany. Upewnij się, że ISiteMapNodeCreator jest zarejestrowany w kontenerze lub zmień konstruktora DynamicSiteMapNodeBuilder.

questionAnswers(1)

yourAnswerToTheQuestion