Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια

C# and .NET Tips and Tricks

Quests in programming in .NET

Ιούνιος 2011 - Δημοσιεύσεις

ASP.NET MVC HTML5 Before and After: The “semantic” markup of HTML5

In this series of posts, we are going to implement a simple website using ASP.NET MVC initially in HTML4 and demonstrate what changes and why in HTML5 for exactly the same implementation.

 

Featuring in this post: The semantic markup/value of HTML5 In this post, we see how the new semantics of HTML5 alter the HTML generated for the homepage of a simple site and why this is important. Imagine you want to implement a website that every day displays a special offer of some kind. In our example, the site is featuring a special offer for a place to go for the weekend. The homepage is as follows:

 

image

 

That is, you have your header where the company’s logo and tagline are displayed (yellow area), a left area where you have some sponsored banners and exactly below an area with previous offers (orange area), your main page where you show the current offer (green area) and the footer with a small navigation menu and information on the site’s creators (white area at the bottom).

Imagine that you have a view model of the following form:

public class HomePageViewModel
{
public Offer CurrentOffer { get; set; }
public IEnumerable<Offer> PreviousOffers { get; set; }

public string BannerImage1File { get; set; }
public string BannerImage1Link { get; set; }

public string BannerImage2File { get; set; }
public string BannerImage2Link { get; set; }
}

The view model consists of the featured offer (the current one) along with a list of the previous offers. Moreover, it has the link and the image file path of the two banners on the left of the homepage. Each offer is represented by an object of the class Offer which has some basic properties related to is such as the Title, Description, Date, Initial price etc. An object of type HomePageViewModel is returned in your “Index” Action of the “Home” controller and is being rendered in the View (Index.cshtml) using Razor. Prior to HTML5 your _Layout.cshtml file defining the main areas of your website as described above would be as follows (body part):

<body>
<div id="container">
<div id="header">
<img style="float:left;width:100px;height:100px" alt="Site Logo" src="../../Images/SiteLogo.png" />
<div style="float:left">
<h1>Good Deals!</h1>
<h4>tagline</h4>
</div>
</div>

<div id="mainContent">
<div id="leftArea">
@RenderSection("LeftArea",false)
</div>
<div id="mainArea">
@RenderBody()
</div>
</div>

<div id="footer">
<div id="menu">
Home | Previous Offers | About | Join us
</div>
&copy; 2011 - Ioannis Panagopoulos - HTML5 Demo Series from
<a href="http://www.progware.org">http://www.progware.org</a>
For more information call: 210666666666
</div>
</div>
</body>

(a visual representation of the site’s structure can be found at the end of the post)

That is, you have each one of the areas defined with a div element carrying a unique id so that you can apply positioning and styling rules through the Site.css file. This is the pretty straightforward approach of developing the visual structure of the homepage of the website. Similarly, the view template for the homepage (Index.cshtml - a strongly-typed View using the HomePageViewModel object returned from the Index action) is as follows (sections only displayed here):

 

@section LeftArea
{
<a href="@Model.BannerImage1Link"><img alt="Ad1" src="@String.Format("Images/{0}", Model.BannerImage1File)" width=170 height=100 /></a><br />
<a href="@Model.BannerImage2Link"><img alt="Ad2" src="@String.Format("Images/{0}", Model.BannerImage2File)" width=170 height=100 /></a><br />
<h1>Previous Deals</h1>
@foreach (var PrevDeal in Model.PreviousOffers)
{
<h2>@PrevDeal.Title</h2>
<img alt="Deal" src="@String.Format("Images/Places/{0}", PrevDeal.RelativePhotoPath)" width=100 height=60 /><br />
@:from: <p>@PrevDeal.InitialPrice.ToString("C")</p>
@:to: <p>@PrevDeal.Price.ToString("C")</p>
@Html.ActionLink("View", "Index", "Offer", new { Id = @PrevDeal.Id }, null)
}
}

<h1>Current Deal!</h1>
<h2>@Model.CurrentOffer.Title</h2>
<img alt="Deal" src="@String.Format("Images/Places/{0}",Model.CurrentOffer.RelativePhotoPath)" width=300 height=180 /><br />
<p>@Model.CurrentOffer.Description.Substring(0, 100)+"..."</p>
from: <p>@Model.CurrentOffer.InitialPrice.ToString("C")</p>
to: <p>@Model.CurrentOffer.Price.ToString("C")</p>
posted on: <p>@Model.CurrentOffer.Date.ToShortDateString() time: @Model.CurrentOffer.Date.ToShortTimeString() </p>
@Html.ActionLink("View","Index", "Offer", new { Id = @Model.CurrentOffer.Id },null)

 

As you may have already realized, all the divs and ids of the divs, are strictly for display-rendering purposes. The HTML of the page does not give any indication whatsoever on the “meaning” of each area of the page. Any crawler or automated process visiting our site will not be able to deduce anything for the content. HTML5 introduces tag elements to use in the place of the divs that have more “semantic” meaning. Therefore the main objective of this post is the replacement of the divs of the page with HTML5 tag elements that give a meaning to the content apart from the strict visual arrangement governing the use of divs in HTML4.

 

So, the first key element of HTML5 is learning this new semantic markup and using it appropriately. And this is exactly what we will do. Actually, the first thing is changing the header of the site enclosed in a div with id=header to the following:

<header class="mainSiteHeader">
<img style="float:left;width:100px;height:100px" alt="Site Logo" src="../../Images/SiteLogo.png" />
<hgroup style="float:left">
<h1>Good Deals!</h1>
<h4>tagline</h4>
</hgroup>
</header>

As you see we define in markup that this is the header of the site (tag header) and within we define the logo and tagline as a group accompanying the header (tag hgroup). In other words we have given semantic information for the header content of our website.

Considering now the main content, we see that there are three semantic sections. One that contains the main offer, one that contains previous offers and one that comprises of the banners. In HTML5, semantic areas are defined with “section” tags. Individual pieces of information within the same section (such as each offer in the previous offers section) are defined with “article” tags. Each article can also have a header and sections. Finally since the area of the two banners is not directly related to the content of the website in HTML5 it should be enclosed within an “aside” tag. The footer of the homepage in HTML5 has its own “footer” tag and the navigation menu is enclosed in “nav” tags. Finally, note that some specific information such as the date of the offer are semantically defined  with specific HTML5 tags such as the “time datetime” tag.

 

The new _Layout.cshtml, using HTML5 markup is as follows:

<body>
<div id="container">
<header class="mainSiteHeader">
<img style="float:left;width:100px;height:100px" alt="Site Logo" src="../../Images/SiteLogo.png" />
<hgroup style="float:left">
<h1>Good Deals!</h1>
<h4>tagline</h4>
</hgroup>
</header>

<section class="mainContent">
<section class="leftArea">
@RenderSection("LeftArea",false)
</section>
<section class="mainArea">
@RenderBody()
</section>
</section>

<footer>
<nav>
Home | Previous Offers | About | Join us
</nav>
&copy; 2011 - Ioannis Panagopoulos - HTML5 Demo Series from <a href="http://www.progware.org">http://www.progware.org</a>
For more information call: 210666666666
</footer>
</div>
</body>

And the Index.cshtml which works with the same controller but with HTML5 markup is as follows:

@section LeftArea
{
<aside>
<a href="@Model.BannerImage1Link"><img src="@String.Format("Images/{0}", Model.BannerImage1File)" width=170 height=100 /></a><br />
<a href="@Model.BannerImage2Link"><img src="@String.Format("Images/{0}", Model.BannerImage2File)" width=170 height=100 /></a><br />
</aside>
<section>
<header class="sectionHeader"><h1>Previous Deals</h1></header>
@foreach (var PrevDeal in Model.PreviousOffers)
{
<article>
<header class="sectionHeader">
<h2>@PrevDeal.Title</h2>
</header>
<img src="@String.Format("Images/Places/{0}", PrevDeal.RelativePhotoPath)" width=100 height=60 />
<br />
from: <p>@PrevDeal.InitialPrice.ToString("C")</p>
to: <p>@PrevDeal.Price.ToString("C")</p>
@Html.ActionLink("View", "Index", "Offer", new { Id = @PrevDeal.Id }, null)
</article>
}
</section>
}
<header><h1>Current Deal!</h1></header>
<article>
<header class="sectionHeader">
<h2>@Model.CurrentOffer.Title</h2>
</header>
<img alt="Deal Image" src="@String.Format("Images/Places/{0}",Model.CurrentOffer.RelativePhotoPath)" width=300 height=180 /><br />
<p>@Model.CurrentOffer.Description.Substring(0, 100)+"..."</p>
from: <p>@Model.CurrentOffer.InitialPrice.ToString("C")</p>
to: <p>@Model.CurrentOffer.Price.ToString("C")</p>
posted on: <time [email protected]("yyyy-MM-dd") pubdate>@Model.CurrentOffer.Date.ToShortDateString() </time> time:<time>@Model.CurrentOffer.Date.ToShortTimeString()</time> </p>
@Html.ActionLink("View","Index", "Offer", new { Id = @Model.CurrentOffer.Id },null)
</article>

Graphically in HTML4 the structure of the site was defined as follows:

 

image

 

And after with HTML5:

image

The two sites with the help of styling with .css are visually the same but the second in HTML5 carries a lot more semantic information.

 

The first step for making  an ASP.NET MVC site using HTML5 is searching for the new HTML5 semantic tags and introducing them to your Views where appropriate. You will find a lot of sites in the web describing which are those new tags and where it is appropriate to use them in your page.

Shout it

Posted: Σάββατο, 25 Ιουνίου 2011 8:16 πμ από iwannis | 2 σχόλια
Δημοσίευση στην κατηγορία: ,
Inversion of Control (IoC) and Dependency Injection (DI) and why they are important.

In this blog post, we are going to see how and when  Dependency Injection (DI) and Inversion of Control(IoC) can be applied for writing nice and maintainable code. Note that although there are plenty of tools out there that give you the ability to apply DI out of the box, in this post we are going to implement such a tool on our own gaining valuable insight on the workings of IoC and DI.

 

Suppose that in your code you have two classes (A,B) like the following:

public class A
{
public A(){}
public void Method1(){ }
public void Method2() { }
}

public class B
{
private A _a;
public B()
{
_a = new A();
_a.Method1();
_a.Method2();
}
}

 

That is, we have a class A that has two methods and class B that has a field of type A which is initialized and used in the constructor. Whenever we have such situation we say that “B depends on A” since B needs to create and use A directly. Also, B “has the control” of the creation of A. We will show that dependency graphically with an arrow as follows:

 

image

 

If you implement a new class A1 with the same functionality as A and want to use A1 in B, then you would need to change in B the type of field _a to A1 and its instantiation and recompile the project. If you use A only in one class in your program and your program is a single .exe file (no .dlls) then the merits of IoC cannot be shown and in my opinion you may introduce an unnecessary overhead if you apply it. But let’s see how this changes if the previous condition does not apply.

 

Suppose now that your app is a single .exe file but you have more than one class using A, say B,C,D. Each one of those classes (B,C,D) have a field of type A and use it in their code (B,C,D depend on A).

 

image

 

Switching now from A to A1 requires you to go to “each and every one” of the classes that use A (in a big project this also means that you have to remember which classes are those-in our example B,C,D) and make the appropriate changes. As you must have realized, such process, is error prone and takes time. This problem is created because B,C,D depend on A and B,C,D have the control of creating instances of A.

 

When you use Inversion of Control in the previous situation (changing A to A1) you only need to change a single line of code. So lets see how this works:

 

  1. We create an interface (IA) that has the methods of A. A and A1 should implement this interface.
  2. All classes that use (depend on) A now should use (depend on) IA.
  3. We either need to pass an instance that implement IA in the constructor of those classes or we need to implement a third class Creator that creates objects that implement IA and B,C,D should use this class to get instances that implement IA.

 

If we pass instances that implement IA in the constructors the code looks like the following:

interface IA {
void Method1();
}

public class A:IA {
public A(){}
public void Method1(){ }
}

public class B {
private IA _a;
public B(IA AImplementation) {
_a = AImplementation;
_a.Method1();
}
}

 

In the initial implementation “B had the control of creating A and B depended on A”. In this implementation “the user of B has the control of creating A and B does not depend on A but on IA”. This is Inversion of Control. Now if C,D also follow the same implementation changing from A to A1 does not affect them at all as long as you pass to their constructors and object of type A1 instead of an object of type A. Therefore the previous issue of having to change B,C,D to switch from A to A1 has been solved by using Ioc.

 

Of course, a lot of you would argue that you still have to change the instantiation of A to A1 to each and every one of the classes that create B,C,D to pass the correct parameter in the constructor. For this reason you can use a creator class (a factory) that returns objects that implement IA and use this to create your classes.

 

If we use a creator class and not pass the IA object in the constructor, the code looks like the following:

interface IA {
void Method1();
}

public class A:IA {
public A(){}
public void Method1(){ }
}

public static class Creator {
public A GetIA() {return new A();}
}

public class B {
private IA _a;
public B() {
_a = Creator.GetIA();
_a.Method1();
}
}

See that now _a in B is of type IA and B asks the Creator to get an instance of A. A implements IA. C,D classes would also use IA and the Creator to get an instance that implements A. A1 would need to implement IA also and switching from A to A1 would only require changing the method GetIA in the creator to return a new instance of A1 instead of A. This “Creator” class is usually called a “factory”.

 

Inversion of Control has enabled such a change to be fast, efficient and error free. You can change from A to A1 by changing one line and you can use a new A2 easily by making it implement IA. The drawback is that the amount of code we have written has tripled.

 

Inversion of Control has also another very important benefit in the case where your project uses a .dll. Imagine that you have your ASP.NET MVC project using a class library project which is your business layer. Then, your final deployment consists of the web app and the library dll. If your class A is part of your library and B is part of your web app and you do not use IoC, each time you change from A to A1 you need to recompile the whole project. On the contrary if you use IoC and a factory, the interface IA resides in the library the creator class (factory) resides also in the library and your B class in the web app uses IA. Therefore changing from A to A1 requires you to recompile only the library (.dll) and not all the project facilitating easy and fast deployment in changes.

 

Now wouldn’t  it be nice if we didn’t have to recompile even the library when changing from A to A1? Just have a way to do that by just changing a setting? Can we inject that dependency (A,A1) somehow without having to recompile? This is what we call “Dependency Injection”. How would we implement this without the help of any other libraries?

 

We could keep in a file the class type that needs to be instantiated for the interface and have our “Creator” class (factory) read this file, find out the name of the class that needs to be instantiated and create it by reflection. This would inject the required class in the dependency and thus the term “Dependency Injection”. This means that with dependency injection you do not have to recompile your app when switching from A to A1. The implementation of the creator class for IA should follow the steps below (full code in the project you can download at the end of the post):

 

  1. Open the file with the pairs (interface to implementation).
  2. Find the class name to instantiate
  3. Use reflection to instantiate class from the assembly
  4. Return new object implementing the interface

 

And the file that holds the pair can contain entries as follows:

 

DIandIOCDemo.IA=DIandIOCDemo.A

 

So when should you use Inversion of Control and Dependency Injection?

 

The general rule of thumb is to use it when you have many classes using the methods of a single one and this one may have more than one different “versions”. For example, you are creating your DB Access repositories and you also need to have some fake ones for your tests. Or you have to versions of a class one with lots of debugging info and one without and want to switch between the two at a deployed application.

 

Note that there are fully blown libraries that handle dependency injection such as spring.netthat you should also check out.

 

The project can be downloaded here

.

Shout it

Posted: Πέμπτη, 9 Ιουνίου 2011 7:45 μμ από iwannis | 1 σχόλια
Δημοσίευση στην κατηγορία: ,