实现新的ISiteMapNodeVisibilityProvider

时间:2013-09-10 14:00:45

标签: c# asp.net-mvc-4 mvcsitemapprovider

我实现了ISiteMapNodeVisibilityProvider

public bool IsVisible(SiteMapNode node, HttpContext context, IDictionary<string, object> sourceMetadata)
        {
            return !context.Request.IsAuthenticated;
        }

但是在新版本中,事物接缝要改变,所以ISiteMapNodeVisibilityProvider看起来像这样:

public interface ISiteMapNodeVisibilityProvider
    {
        bool AppliesTo(string providerName);
        bool IsVisible(ISiteMapNode node, IDictionary<string, object> sourceMetadata);
    }

我只是想知道如何在新版本中实现我的旧逻辑?它不包含context

3 个答案:

答案 0 :(得分:2)

我认为应该这样做:

public class AuthenticatedVisibilityProvider : SiteMapNodeVisibilityProviderBase
    {
        #region ISiteMapNodeVisibilityProvider Members

        /// <summary>
        /// Determines whether the node is visible.
        /// </summary>
        /// <param name="node">The node.</param>
        /// <param name="sourceMetadata">The source metadata.</param>
        /// <returns>
        ///     <c>true</c> if the specified node is visible; otherwise, <c>false</c>.
        /// </returns>
        public override bool IsVisible(ISiteMapNode node, IDictionary<string, object> sourceMetadata)
        {
            return HttpContext.Current.Request.IsAuthenticated;
        }

        #endregion
    }

答案 1 :(得分:1)

这个怎么样:

public class MyImplementation:ISiteMapNodeVisibilityProvider
{
    HttpContext _context;
    public MyImplementation(HttpContext context)
    {
          _context = context;
    }

    public bool IsVisible(ISiteMapNode node, IDictionary<string, object> sourceMetadata){
       return !_context.Request.IsAuthenticated;
    }
    //example implementation of AppliesTo from
    //one of base classes of MVCSiteMapProvider
    //https://github.com/maartenba/MvcSiteMapProvider/blob/master/src/MvcSiteMapProvider/MvcSiteMapProvider/SiteMapNodeVisibilityProviderBase.cs
    public virtual bool AppliesTo(string providerName)
    {
        return this.GetType().ShortAssemblyQualifiedName().Equals(providerName, StringComparison.InvariantCulture);
    }
}

换句话说,将上下文作为参数实例化。

ISiteMapNodeVisibilityProvider provider = new MyImplementation(httpContext);
bool isVisible = provider.IsVisible;

答案 2 :(得分:0)

正如upgrade document所指出的,您不需要实施AppliesTo()。您可以从SiteMapNodeVisibilityProviderBase继承:

// Using Internal DI
public class MyImplementation : SiteMapNodeVisibilityProviderBase
{
    HttpContextBase _context;
    public MyImplementation()
    {
          _context = new HttpContextWrapper(HttpContext.Current);
    }

    public override bool IsVisible(ISiteMapNode node, IDictionary<string, object> sourceMetadata){
       return !_context.Request.IsAuthenticated;
    }
}

// Using External DI
public class MyImplementation : SiteMapNodeVisibilityProviderBase
{
    HttpContextBase _context;
    public MyImplementation(HttpContextBase context)
    {
          _context = context;
    }

    public override bool IsVisible(ISiteMapNode node, IDictionary<string, object> sourceMetadata){
       return !_context.Request.IsAuthenticated;
    }
}

传递HttpContextBase比HttpContext更好,因为如果你决定开始进行单元测试,它很容易被模拟。然后,您可以使用名为HttpContextWrapper的HttpContextBase的.NET默认实现来包装静态实例。

请注意,内部DI容器需要默认的公共构造函数,因为它使用Reflection来实例化类。但是,如果使用外部DI容器,可以将HttpContextBase传递给您的类,因为如果您在容器中注册了它们,它将解析构造函数参数(同样,它将使其可以单元测试)。

在StructureMap中(对于外部DI),注册码如下所示:

container.For<System.Web.HttpContext>().Use(t => System.Web.HttpContext.Current);
container.For<System.Web.HttpContextBase>().Use<System.Web.HttpContextWrapper>();