Tag: code

Update on ASP.NET Forms Bootstrap Menu Control

I finally took the time to move my ASP.NET Forms Bootstrap Menu Control code over to a GitHub repository. Because of the move, I’ve closed the comments on the original post in hopes of moving all discussion regarding the control to its repository.

I’ve also built out 2 separate example projects. The first shows how to use the control with just the class file. The second shows how to use the control by referencing the project from a separate class library.

Advertisements

ASP.NET Forms Bootstrap Menu Control

UPDATE: I have closed the comments for this post. If you’d like to discuss the ASP.NET Forms Bootstrap Menu Control, please visit the GitHub repository located at: https://github.com/knight0323/aspnet-forms-bootstrap-menu


When I couldn’t find an ASP.NET Form menu control that was compatible with Bootstrap 3.1, I did what every other developer would do: I created one. Enjoy!

Here’s the HTML markup view:

<div class="navbar navbar-inverse navbar-static-top" role="navigation">
    <div class="container" style="padding: 0; margin: 0;">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
        </div>
        <div class="navbar-collapse collapse">
            <jk:BootstrapMenu ID="BootstrapMenu1" runat="server">
                <Items>
                    <asp:MenuItem Text="Home" NavigateUrl="#" />
                    <asp:MenuItem Text="About" NavigateUrl="#" />
                    <asp:MenuItem Text="Contact" NavigateUrl="#" />
                    <asp:MenuItem Text="Drop Down">
                        <asp:MenuItem Text="Action" NavigateUrl="#" />
                        <asp:MenuItem Text="Another action" NavigateUrl="#" />
                        <asp:MenuItem Text="Something else here" NavigateUrl="#" />
                    </asp:MenuItem>
                    <asp:MenuItem Text="Help" NavigateUrl="#" />
                    <asp:MenuItem Text="Nothing" />
                </Items>
            </jk:BootstrapMenu>
        </div><!--/.nav-collapse -->
    </div>
</div>

Here’s the HTML markup view for using with a SiteMapDataSource:

<div class="navbar navbar-inverse navbar-static-top" role="navigation">
    <div class="container" style="padding: 0; margin: 0;">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
        </div>
        <div class="navbar-collapse collapse">
            <jk:BootstrapMenu ID="BootstrapMenu2" runat="server" DataSourceId="SiteMapDataSource1" />
            <asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" ShowStartingNode="False" />
        </div><!--/.nav-collapse -->
    </div>
</div>

In either case you’ll need a page directive

<%@ Register tagPrefix="jk" assembly="JK.Core.Web" namespace="JK.Core.Web.Controls" %>

Updates:

  • 2017 January 23: Closed comments to push conversation to GitHub repository.
  • 2015 January 19: Added zip file sample project for download to OneDrive.
  • 2014 August 15: Added page directive needed to use control in page markup
  • 2014 April 11: Updated to work with SiteMapDataSource

Lazy Strategy Pattern

The following are some code samples that show how to use Lazy to clean up how your objects are initialized when using the Strategy pattern in .NET. The following code is taken from the DimeCast.Net Strategy pattern video. It uses an enum to select the correct logging strategy and logs the given message. The original code from the video before Lazy is applied looks like (by the way, I’m only posting the sections relevant to strategy and lazy):

public class LoggingService : ILoggingService
{
    private readonly Dictionary<LoggingStrategy, Logger> strategies;

    public LoggingService()
    {
        this.strategies = new Dictionary<LoggingStrategy, Logger>();
        this.DefineStrategies();
    }

    private void DefineStrategies()
    {
        this.strategies.Add(LoggingStrategy.Event, new EventLogger());
        this.strategies.Add(LoggingStrategy.Repository, new RepositoryLogger());
        this.strategies.Add(LoggingStrategy.Trace, new TraceLogger());
    }
}

Here is the same code using the Lazy<T> class in the System namespace.

public class LazyLoggingService : ILoggingService
{
    private readonly Dictionary<LoggingStrategy, Lazy<Logger>> strategies;

    public LazyLoggingService()
    {
        this.strategies = new Dictionary<LoggingStrategy, Lazy<Logger>>();
        this.DefineStrategies();
    }

    private void DefineStrategies()
    {
        this.strategies.Add(LoggingStrategy.Event, new Lazy<Logger>(() => new EventLogger()));
        this.strategies.Add(LoggingStrategy.Repository, new Lazy<Logger>(() => new RepositoryLogger()));
        this.strategies.Add(LoggingStrategy.Trace, new Lazy<Logger>(() => new TraceLogger()));
    }
}

And one final time just in case you don’t have access to Lazy<T>. This uses delegates to accomplish the same thing as the Lazy<T> class. I’ll be using the Func<TResult> delegate.

public class DelegateLoggingService : ILoggingService
{
    private readonly Dictionary<LoggingStrategy, Func<Logger>> strategies;

    public DelegateLoggingService()
    {
        this.strategies = new Dictionary<LoggingStrategy, Func<Logger>>();
        this.DefineStrategies();
    }

    private void DefineStrategies()
    {
        this.strategies.Add(LoggingStrategy.Event, () => new EventLogger());
        this.strategies.Add(LoggingStrategy.Repository, () => new RepositoryLogger());
        this.strategies.Add(LoggingStrategy.Trace, () => new TraceLogger());
    }
}

Now that all the code is out of the way, let’s talk a little about why you would want to use this. Let’s look at the original code sample. The DefineStrategies function initializes a Logger object and adds it to the Dictionary. Every single Dictionary.Add call in the original code is initializing an object. That’s additional memory and processing time for every object. By using Lazy(or the delegate method shown above), you postpone the initialization of the object until you actually ask for it.

Lazy initialization may not work well for everything but I’ve found that it makes strategy implementations much more lean and efficient in terms of machine resources.

.NET String Concatenation

String concatenation is a tool on every developer’s tool belt but in .NET there are multiple ways to accomplish it. There are also a lot of conflicting articles, posts, etc. on the subject. When should you use StringBuilder? When should you use string formatting? This article will hopefully shine some light on when to use each method.

Which Methods Were Tested?

How Were They Tested?

A console application was prepared to test operation scenarios. The scenarios were timed using the System.Diagnostics.Stopwatch class. The full Visual Studio solution can be found in my CodePlex project.

What Were the Results?

Scenario 1: Loop Concatenation

The Loop Concatenation scenario was built to test string concatenation within a loop. This data set had the most straight-forward results. The StringBuilder class gives the best performance when using concatenation in this scenaraio.

Loop Concatenation Results (in milliseconds)

Code sample using StringBuilder in this scenario:

var builder = new StringBuilder();

for (int i = 0; i < this.iterations; i++)
{
    builder.Append("x");
}

var testString = builder.ToString();

Scenario 2: Full Name Concatenation

The Full Name Concatenation scenario was built to test simple string concatenation in which few concatenations occur. It concatenates first name, a space, and last name. This is commonly used to build display names for a UI. These results point to the String.Concat method as the most efficient way to concatenate small numbers of strings.

Full Name Concatenation Results (in ticks)

Code sample using String.Concat in this scenario:

string first = "John";
string last = "Deaux";
string fullName = string.Concat(first, " ", last);

Scenario 3: Long Text Concatenation

The Long Text Concatenation scenario was built to test long concatenations in which many concatenations occur. It simulates building the body of an email message. These results also point to the String.Concat method as the most efficient. Comparing the prior scenario with this scenario you can begin to see pattern. As you add concatenations, the efficiency of String.Format and StringBuilder (when out of a looping scenario) declines.

Long Text Concatenation Results (in ticks)

Code sample using String.Concat in this scenario:

string newLine = System.Environment.NewLine;
string name = "John Deaux";
string email = "john.deaux@123.me";
string subject = "The Subject of the Message";
string product = "ABC";
string feature = "XYZ";
string body = "The comment(s) made about product/feature.";

string[] values = new[]
    {
        "Name: ", name, newLine,
        "Email: ", email, newLine,
        "Subject: ", subject, newLine,
        "Product: ", product, newLine,
        "Feature: ", feature, newLine,
        "Message: ", newLine, body
    };

var emailBody = string.Concat(values);

Scenario 4: Date Concatenation

The Date Concatenation scenario was built to test the formatting of dates. It formats a date into the sortable format of 2011-12-31T15:30:15. Of the people I’ve talked to about this little experiment, this one has surprised the most. Why? Because it is highly touted by articles, books, and even Microsoft as the way to format data and it’s extremely inefficient. The String.Format method is slower and less efficient than every other method tested, including the StringBuilder class, for formatting DateTime objects as strings.

Date Concatentation Results (in ticks)

Code sample using String.Concat in this scenario:

DateTime date = DateTime.Now;

var values = new[]
    {
        date.Year.ToString("0000"),
        "-",
        date.Month.ToString("00"),
        "-",
        date.Day.ToString("00"),
        "T",
        date.Hour.ToString("00"),
        ":",
        date.Minute.ToString("00"),
        ":",
        date.Second.ToString("00")
    };

var sortable = string.Concat(values);

Yes, you did read that correctly. The above code is a lot faster and more efficient than:

var sortable = string.Format("{0:u}", DateTime.Now);
// or
var sortable = string.Format("{0:yyyy-MM-ddTHH:mm:ss}", DateTime.Now);

Back to Basics: System.String

For such a simple concept, the string class is, in my opinion, one of the most complex classes in the System namespace. The MSDN page for String Class is 53 printed pages excluding the 2 additional pages of comments.

What is System.String?

In the .NET framework, the string type is a reference type. It is not a value type as is often the belief. It is an object that consists of a collection of System.Char values in sequential order. Characters within the string can be referenced as follows:

string foo = "bar";
char r = foo[2];

Immutable

The string type is also immutable. You cannot change the contents of a string without reflection or unsafe code. The methods, operators, etc. that appear to modify a string actually return a new string with the modified contents. The Replace function of the string object is a great example of this. You cannot simply call the Replace method. You have to return the results of the method to a string variable.

string foo = "abc";
foo = foo.Replace("abc", "xyz");

Concatenation and the Compiler

The compiler does some interesting things when working with strings. For example, when concatenating with variables in a single statement:

string foobar = foo + " " + bar;

// compiler sees the above as:
string foobar = string.Concat(foo, " ", bar);

When you use constants such as literals and const string members, the compiler knows that all the parts are constant and it does all the concatenation at compile time, storing the full string in the compiled code.

string foobar = "foo" + " " + "bar";

// compiler sees the above as:
string foobar = "foo bar";
const string foo = "foo";
string foobar = foo + " " + "bar";

// compiler sees the above as:
string foobar = "foo bar";

String.Empty versus “”

And finally, there is a difference between string.Empty and “”. When you use “”, .NET creates an object but when you use string.Empty it does not. The difference may be small, but its a difference that can make a performance impact.

string foo = ""; // creates an object
string bar = string.Empty; // doesn't create an object