0

我有这样的实施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

4

3 回答 3

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
    }
于 2013-11-03T21:50:26.657 回答
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;
于 2013-09-10T14:06:06.413 回答
0

正如升级文档中所指出的,您不需要实现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 容器需要一个默认的公共构造函数,因为它使用反射来实例化类。但是,如果使用外部 DI 容器,您可以将 HttpContextBase 传递到您的类中,因为如果您将构造函数参数注册到容器中,它将解析构造函数参数(同样,它将使其可单元测试)。

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

container.For<System.Web.HttpContext>().Use(t => System.Web.HttpContext.Current);
container.For<System.Web.HttpContextBase>().Use<System.Web.HttpContextWrapper>();
于 2013-09-11T07:25:53.203 回答