Reputation: 1309
I had such implementation of ISiteMapNodeVisibilityProvider
public bool IsVisible(SiteMapNode node, HttpContext context, IDictionary<string, object> sourceMetadata)
{
return !context.Request.IsAuthenticated;
}
But in new version the things seams to be changed so ISiteMapNodeVisibilityProvider
looking like that:
public interface ISiteMapNodeVisibilityProvider
{
bool AppliesTo(string providerName);
bool IsVisible(ISiteMapNode node, IDictionary<string, object> sourceMetadata);
}
I am just wondering how to implement my old logic in the new version? It is does not contains context
Upvotes: 0
Views: 933
Reputation: 28259
I believe it should be done like that:
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
}
Upvotes: 2
Reputation: 56849
As pointed out in the upgrade document, you don't need to implement AppliesTo(). You can inherit from 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;
}
}
It is also better to pass HttpContextBase than HttpContext because it can be easily mocked if you decide to start doing unit testing. You can then use the .NET default implementation of HttpContextBase called HttpContextWrapper to wrap the static instance.
Note that the internal DI container requires a default public constructor because it uses Reflection to instantiate the class. However, you can pass the HttpContextBase into your class if using an external DI container because it will resolve the constructor parameters if you have them registered with the container (and again, it will make it unit testable).
In StructureMap (for external DI), the registration code would look like this:
container.For<System.Web.HttpContext>().Use(t => System.Web.HttpContext.Current);
container.For<System.Web.HttpContextBase>().Use<System.Web.HttpContextWrapper>();
Upvotes: 0
Reputation: 3556
How about this:
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);
}
}
In other words instantiate the class with context as parameter.
ISiteMapNodeVisibilityProvider provider = new MyImplementation(httpContext);
bool isVisible = provider.IsVisible;
Upvotes: 1