Asp.net mvc 4 如何实现自定义SiteMapNodeProvider
我正在尝试调整MvcSiteMapProvider,以便根据存储在数据库中的一些信息创建面包屑 帖子中的答案听起来很有希望,所以我实现了自己的SiteMapNodeProvider。但后来我不知道如何连接,所以使用了新实现的SiteMapNodeProvider,而不是静态xml文件(“Mvc.sitemap”) 当我在项目中使用SimpleInjector时,我在已经存在的注入初始化代码中调用了setup方法Asp.net mvc 4 如何实现自定义SiteMapNodeProvider,asp.net-mvc-4,mvcsitemapprovider,Asp.net Mvc 4,Mvcsitemapprovider,我正在尝试调整MvcSiteMapProvider,以便根据存储在数据库中的一些信息创建面包屑 帖子中的答案听起来很有希望,所以我实现了自己的SiteMapNodeProvider。但后来我不知道如何连接,所以使用了新实现的SiteMapNodeProvider,而不是静态xml文件(“Mvc.sitemap”) 当我在项目中使用SimpleInjector时,我在已经存在的注入初始化代码中调用了setup方法 public static void Initialize() {
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 ...
}
MVCSItemApproviderContaineInitializer类由包创建:“Mvcsitemapprovider.mvc4.di.simpleinjector/4.4.5”
有人知道如何让我的项目使用新创建的SiteMapNodeProvider吗?
我在官方文件中找不到任何有关这方面的文件
编辑:我尝试了你的建议(甚至删除了旧的DI内容,只使用了nuget软件包中的一个),但仍然出现了错误。。。
以下是我的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);
}
}
publicstaticvoid设置(容器)
{
bool securityTrimmingEnabled=false;
bool enableLocalization=true;
字符串absoluteFileName=HostingEnvironment.MapPath(“~/Mvc.sitemap”);
TimeSpan absoluteCacheExpiration=TimeSpan.FromMinutes(5);
字符串[]includeAssembliesForScan=新字符串[]{“testsitemap”};
//允许通过GetAllInstances解析数组的扩展(本机基于IEnumerable)。
//资料来源:https://simpleinjector.codeplex.com/wikipage?title=CollectionRegistrationExtensions
AllowToResolveArraySandList(容器);
var currentAssembly=typeof(MvcSiteMapProviderContainerInitializer)。程序集;
var siteMapProviderAssembly=typeof(SiteMaps).Assembly;
var allAssemblies=新程序集[]{currentAssembly,siteMapProviderAssembly};
var excludeTypes=新类型[]
{
类型(SiteMapNodeVisibilityProviderStrategy),
类型(SiteMapXmlReservedAttributeNameProvider),
类型(SiteMapBuilderSetStrategy),
类型(控制器类型解析工厂),
//eric-b添加了2013-06-28,以避免默认的单身登记:
类型(XmlSiteMapController),
//eric-b为SimpleInjector添加了2013-06-28。验证方法:
类型(参数集合),
类型(MvcResolver),
类型(MvcSiteMapProvider.SiteMap),
类型(MetarobotsValue集合),
类型(角色集合),
类型(SiteMapPluginProvider),
类型(控制器类型分解器),
类型(RouteValueDictionary),
类型(属性和指令)
,类型(SiteMapNodeCreator)
};
var multipleImplementationTypes=新类型[]
{
类型(IsItemaNodeUrlResolver),
类型(IsItemaNodeVisibilityProvider),
类型(IDynamicNodeProvider)
};
//具有匹配名称(减去“I”)的接口的单个实现。
CommonConventions.RegisterDefaultConventions(
(interfaceType,implementationType)=>container.RegisterSingle(interfaceType,implementationType),
新程序集[]{siteMapProviderAssembly},
诸位,
排除类型,
字符串(空);
//基于策略的扩展点的多种实现
CommonConventions.RegisteralLimpElementationsOfInterfaceSingle(
(interfaceType,implementationTypes)=>container.Registeral(interfaceType,implementationTypes),
多种实施类型,
诸位,
新类型[0],
“^Composite”);
container.Register();
//可见性提供者
container.RegisterSingle(()=>
新SiteMapNodeVisibilityProviderStrategy(
container.GetAllInstances
().
ToArray(),string.Empty));
//传入全局controllerBuilder引用
container.RegisterSingle(()=>ControllerBuilder.Current);
container.RegisterSingle();
container.RegisterSingle();
container.RegisterSingle(()=>
新建ControllerTypeResolverFactory(新字符串[0],
container.GetInstance
(),
container.GetInstance
()));
//配置安全性
container.registeral(typeof(authorizeAttributeAlmodule),typeof(XmlRolesAclModule));
container.RegisterSingle(()=>newcompositeaclmodule(container.GetAllInstances().ToArray());
//设置缓存
container.RegisterSingle(()=>System.Runtime.Caching.MemoryCache.Default);
RegisterSingleOpenGeneric(typeof(ICacheProvider)、typeof(RuntimeCacheProvider));
RegisterSingle(()=>新的RuntimeFileCacheDependency(absoluteFileName));
container.RegisterSingle(()=>新缓存详细信息(absoluteCacheExpiration、TimeSpan.MinValue、container.GetInstan
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 (required)
MvcSiteMapProviderContainerInitializer.SetUp(container);
// Setup global sitemap loader (required)
MvcSiteMapProvider.SiteMaps.Loader = container.GetInstance<ISiteMapLoader>();
// Check all configured .sitemap files to ensure they follow the XSD for MvcSiteMapProvider (optional)
var validator = container.GetInstance<ISiteMapXmlValidator>();
validator.ValidateXml(HostingEnvironment.MapPath("~/Mvc.sitemap"));
// Register the Sitemaps routes for search engines (optional)
XmlSiteMapController.RegisterRoutes(RouteTable.Routes); // NOTE: You can put this in your RouteConfig.cs file if desired.
//... register some other stuff for your project here ...
}
Injection.Global.RegisterMvcControllers(typeof(MvcSiteMapProvider.SiteMaps).Assembly);
// 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>())));
typeof(SiteMapNodeCreator),
typeof(DynamicSiteMapNodeBuilder)