Paulo Morgado

.NET Development & Architecture

This Blog

Syndication

Search

Tags

News

Unit Test Today! Get Typemock Isolator!

Projects

Books

 

Visitors

Visitor Locations

Community

Email Notifications

Archives

Profile

Disclaimer

The opinions and viewpoints expressed in this site are mine and do not necessarily reflect those of Microsoft, my employer or any community that I belong to. Any code or opinions are offered as is. Products or services mentioned are purchased by me, made available to me by my employer or the manufacturer/vendor which doesn't influence my opinion in any way.

August 2008 - Posts

Clone Detective For Visual Studio

Clone Detective for Visual Studio

Clone Detective is a tool that integrates with Visual Studio and uses the ConQAT (Continuous Quality Assessment Toolkit) to analyze C# projects and search for duplicated source code.

Watch the videos and see if this is the tool you were looking for.

Posted Thu, Aug 28 2008 23:41 by Paulo Morgado | with no comments

E-Reference Library Subscription Discount Offer for The Community

Microsoft Press has created an exclusive discount URL for the E-Reference Library that MVPs can pass along to the broader community without any limitations or restrictions.

To create a trial subscription, community referrals should use the Trial URL (http://microsofteref2.books24x7.com/promo.asp?ref=mvptry).

Any community referrals who subscribe to E-Reference Libraries through the Subscription URL (http://microsofteref2.books24x7.com/promo.asp?ref=mvpbuy) will receive a 40% discount on a one-year subscription.

This discount offer ends on September 30, 2008.

Posted Thu, Aug 21 2008 23:36 by Paulo Morgado | with no comments

Filed under: , ,

StyleCop 4.3 Is Out

The StyleCop team announced the release of a version 4.3 of the StyleCop tool. You can get it from here.

On this version there are some bug fixes, new rules and documentation.

Also in this version, the list of errors and warnings goes to the Errors List window like with the compilers. I whish that the errors and warnings would also be sent to the Output window.

SDK documentation on how to author custom rules and integrate the tool with custom build environments is expected soon.

Posted Thu, Aug 21 2008 0:36 by Paulo Morgado | with no comments

Lutz Roeder’s .NET Reflector Is Now Red Gate’s .NET Reflector

Let’s face it, if you don’t know .NET Reflector, you can never claim to be a .NET developer.

Today Red Gate announced the acquisition of Lutz Roeder’s .NET Reflector.

On .NET Reflector’s page, Red Gate states that “will continue to maintain a free version for the benefit of the community”.

You can read an interview with Lutz Roeder and James Moore (general manager of .NET Developer Tools at Red Gate) at simple-talk.

James doesn’t know yet how to improve Reflector, but I do. Reflector needs a major improvement on UI usability and performance. Let’s see if I can come up with a list:

  • For me, search as you type is not a good idea as it is in Reflector.
  • Still in the search theme, search as you type would be nice for the active code window.
  • I cannot understand why changing any of the options fires a total repaint and lost of the view of the active code item.
  • Settings like code, documentation and number formatting should possible to change on the fly with a simple toolbar click.

I’m sure Red Gate is more than capable of taking good care of .NET Reflector.

Posted Wed, Aug 20 2008 23:34 by Paulo Morgado | with no comments

Typemock Racer Alpha Is Out

Typemock has released an alpha version of its newest product: Typemock Racer.

Typemock Racer is the tool that uses dynamic and static analysis to find deadlocks in .NET code that had been previously announced by Roy Osherove.

Posted Wed, Aug 20 2008 22:50 by Paulo Morgado | with no comments

Filed under: , , , ,

Typemock Isolator 5.0 Is Out With Its New AAA API

Typemock has released version 5.0 of its unit testing tool: Isolator. Check out the release notes.

This new version comes with a new API: Arrange Act Assert:

I’ll have to say that I liked Isolator better over Isolate.

Also new in this version is the inclusion of the help file in the installation package.

Posted Wed, Aug 20 2008 22:33 by Paulo Morgado | with no comments

VHD Resizer: Tool For Resizing VHD Files

While installing SQL Server 2008 in a Virtual PC virtual machine I run out of disk space.

Looking around, I found this great tool: VHD Resizer. Registration is required to download the tool.

Posted Sun, Aug 17 2008 23:13 by Paulo Morgado | 4 comment(s)

Filed under: , ,

.NET 3.5 SP1, VS2008 SP1 And TFS2008 SP1 Released

Microsoft .NET Framework 3.5 Service Pack 1

Microsoft Visual Studio 2008 Service Pack 1 (iso)

Visual Studio 2008 Team Foundation Server Service Pack 1

Posted Tue, Aug 12 2008 1:20 by Paulo Morgado | with no comments

More On Another Way For Using The “using” Keyword

In the past I presented another possible use for the using keyword: as hints on LINQ.

I’ve been giving some thought about this lately and refined my proposal.

var q = from person in personCollection using MyEnumerableExtensions
        group person by person.LastName into g using new MyOtherComparer()
        orderby g.Key using new MyComparer()
        select person;

The above query would be converted to:

var q = MyEnumerableExtensions.OrderBy<string, Person>(
    MyEnumerableExtensions.GroupBy<string, Person>(
        personCollection,
        person => person.LastName,
        new MyComparer(),
    ),
    g => g.Key,
    mew MyOtherComparer()
);

What do you think of this?

Posted Mon, Aug 11 2008 1:47 by Paulo Morgado | 2 comment(s)

Filed under: , , , , ,

How About Property Assignment And Collection Adding Like Object And Collection Initializers In C#?

C# 3.0 introduced object and collection initializers. It is now easier to initialize objects or collections:

var person = new Person { FirstName = "Paulo", LastName = "Morgado" };

var persons = new List<Person> {
    new Person { FirstName = "Paulo", LastName = "Morgado" },
    new Person { FirstName = "Luís", LastName = "Abreu" }
};

var personDirectory = new Dictionary<string, Person> {
    { "Lisboa", new Person { FirstName = "Paulo", LastName = "Morgado" } },
    { "Funchal", new Person { FirstName = "Luís", LastName = "Abreu" } }
};

Wouldn't be nice to be able to do the same on already created objects and collections?

But, what would the syntax used be? Something like this?

var person = new Person();
person = { FirstName = "Paulo", LastName = "Morgado" };

var persons = new List<Person>();
persons += {
    new Person { FirstName = "Paulo", LastName = "Morgado" },
    new Person { FirstName = "Luís", LastName = "Abreu" }
};

var personDirectory = new Dictionary<string, Person>();
personDirectory += {
    { "Lisboa", new Person { FirstName = "Paulo", LastName = "Morgado" } },
    { "Funchal", new Person { FirstName = "Luís", LastName = "Abreu" } }
};

What do you think of this?

Posted Mon, Aug 11 2008 0:27 by Paulo Morgado | 5 comment(s)

Filed under: , , , ,

Visual Studio 2008 Service Pack 1 Expected Next Week

According to the MSDN Subscriptions home page, we should expect Visual Studio 2008 Service Pack 1 availability after August 11, 2008.

Posted Fri, Aug 8 2008 1:26 by Paulo Morgado | 1 comment(s)

Microsoft Releases SQL Server 2008

SQL Server 2008 is finally out and comes with the Entity Framework, which means that SP1 for Visual Studio 2008 and the .NET Framework is almost out.

Posted Wed, Aug 6 2008 23:44 by Paulo Morgado | with no comments

Serialized In-Process ASP.NET Session State Store

 

ASP.NET provides out of the box three session state stores:

Provider Description
InProc

Session state is stored in the ASP.NET cache.

SQLServer

Session state is stored out-of-process in an SQL Server database.

StateServer

Session state is stored out-of-process in an ASP.NET state service.

Because with SQLServer and StateServer providers the state must cross the AppDomain boundary it needs to be serialized when stored and deserialized when loaded. Because the state needs to be loaded and stored on each request, it is only available from the PostAcquireRequestState to the ReleaseRequestState events. And, because of serialization and deserialization, all objects stored must be serializable any reference held to one of the session state items won’t be to the same item after being deserialized.

On the other hand, with the InProc provider, the state will never be serialized or deserialized, which means that objects don’t need to be serializable and any reference to an item in the state is always a reference to the item in the state even before the PostAcquireRequestState event and after the ReleaseRequestState event.

In practice, developers use the InProc provider and applications are deployed to production using the SQLServer provider. This usually leads to application errors, like storing non serializable objects in the state, that are only uncovered in production. That’s why I’ve written a serializable in-process session state store. You can find the sources here.

Posted Mon, Aug 4 2008 2:09 by Paulo Morgado | 2 comment(s)

Filed under: , , , , ,

C# And Visual Basic Generate Different Expression Trees

(This was pointed out to me by Frans Bouma and explained by Jon Skeet)

Imagine you have this set of classes:

public class A
{
    public virtual string P
    {
        get { return "A"; }
    }
}

public class B : A
{
}

public class C : B
{
    public override string P
    {
        get { return "C"; }
    }
}

And this class:

public static class Reporter
{
    public static void Report<T>(T target, Expression<Func<T, string>> expression)
    {
        Console.WriteLine("Expression: {0}", expression);
        Console.WriteLine("\tDeclaring Type: {0}", ((expression as LambdaExpression).Body as MemberExpression).Member.DeclaringType);
        Console.WriteLine("\tInvocation Result: {0} for {1}", expression.Compile().Invoke(target), target.GetType());
        Console.WriteLine();
    }
}

The above class writes to the console the lambda expression, the declaring type of the property and the value of the property for the target and the target’s type.

Now, let’s look at what happens when used from this C# code:

Reporter.Report(new C(), (A a) => a.P);
Reporter.Report(new C(), (B b) => b.P);
Reporter.Report(new C(), (C c) => c.P);

Reporter.Report(new B(), (A a) => a.P);
Reporter.Report(new B(), (B b) => b.P);

Reporter.Report(new A(), (A a) => a.P);

The output will be:

Expression: a => a.P
        Declaring Type: A
        Invocation Result: C for C

Expression: b => b.P
        Declaring Type: A
        Invocation Result: C for C

Expression: c => c.P
        Declaring Type: A
        Invocation Result: C for C

Expression: a => a.P
        Declaring Type: A
        Invocation Result: A for B

Expression: b => b.P
        Declaring Type: A
        Invocation Result: A for B

Expression: a => a.P
        Declaring Type: A
        Invocation Result: A for A

On the other hand, if used from the equivalent Visual Basic code:

Reporter.Report(New C(), Function(a As A) a.P)
Reporter.Report(New C(), Function(b As B) b.P)
Reporter.Report(New C(), Function(c As C) c.P)

Reporter.Report(New B(), Function(a As A) a.P)
Reporter.Report(New B(), Function(b As B) b.P)

Reporter.Report(New A(), Function(a As A) a.P)

The output will be:

Expression: a => a.P
        Declaring Type: A
        Invocation Result: C for C

Expression: b => b.P
        Declaring Type: A
        Invocation Result: C for C

Expression: c => c.P
        Declaring Type: C
        Invocation Result: C for C

Expression: a => a.P
        Declaring Type: A
        Invocation Result: A for B

Expression: b => b.P
        Declaring Type: A
        Invocation Result: A for B

Expression: a => a.P
        Declaring Type: A
        Invocation Result: A for A

Why the differences? It’s because of each language’s specification and compiler:

  • The C# compiler will issue a virtual call to the virtual member in the class where it’s declared as virtual.
  • The Visual Basic compiler will issue a virtual call to the overriding member on the class that overrides it.

Posted Mon, Aug 4 2008 1:23 by Paulo Morgado | 1 comment(s)

IIS/ASP.NET Cookieless Support Not Working As Expected

In one of the environments I work, cookies cannot be used because the pages run inside web browser controls running on a client application and cookies end up being shared by all browsers.

Fortunately, ASP.NET allows us to persist some cookies as part of the URL.

To persist the session state identifier cookie in the URL we just need to add the following configuration:

<configuration>
  <system.web>
    <sessionState cookieless="UseUri" />
  </system.web>
</configuration>

and you’ll get URLs like this:

http://localhost/Cookieless/(S(jcmwek3ja0lvdpbwoacpjirv))/default.aspx

The way IIS and ASP.NET do this is by IIS removing the section between parenthesis after the virtual directory path and adding the AspFilterSessionId HTTP header to the request. Than, ASP.NET picks it up and extracts the cookie.

I wrote this simple page to demonstrate this working:

<%@ Page Language="C#" AutoEventWireup="true" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <table>
            <tr>
                <td>Raw URL</td>
                <td><%= Request.RawUrl %></td>
            </tr>
            <tr>
                <td>Cookiless Cookies<br />AspFilterSessionId Request HTTP Header</td>
                <td><%= Request.Headers["AspFilterSessionId"] %></td>
            </tr>
            <tr>
                <td>Session ID</td>
                <td><%= Session.SessionID %></td>
            </tr>
        </table>
    </div>
    </form>
</body>
</html>

For the above URL, we'll get a page like this:

Raw URL /Cookieless/default.aspx
Cookiless Cookies
AspFilterSessionId Request HTTP Header
S(jcmwek3ja0lvdpbwoacpjirv)
Session ID jcmwek3ja0lvdpbwoacpjirv

IIS strips these cookies even for serving static content like cascading stylesheets.

You can test this by creating a default theme. You can do this by adding a Default folder under the App_Themes folder and adding a Styles.css file to it:

body
{
    background-color: Yellow;
}
table, tr, td
{
    border: thin solid black;
}

and setting the theme as default using the following configuration:

<configuration> <system.web> <sessionState cookieless="UseUri" /> <pages theme="Default"/> </system.web> </configuration>

And you'll get a "pretier" page:

Raw URL /Cookieless/default.aspx
Cookiless Cookies
AspFilterSessionId Request HTTP Header
S(jcmwek3ja0lvdpbwoacpjirv)
Session ID jcmwek3ja0lvdpbwoacpjirv

If you have special needs for your session state identifiers, you can implement your own session identifier manager.

But if you want to use cookieless cookies, you only have one way to do it: extend the SessionIDManager class:

public class SessionIdManager : System.Web.SessionState.SessionIDManager
{
    public override string CreateSessionID(System.Web.HttpContext context)
    {
        string id = System.Guid.NewGuid().ToString("B");

        return id;
    }

    public override bool Validate(string id)
    {
        try
        {
            new System.Guid(id);
            return true;
        }
        catch
        {
            return false;
        }
    }
}

and configure the session state module to use it:

<configuration>
  <system.web>
    <sessionState cookieless="UseUri" sessionIDManagerType="SessionIdManager" />
    <pages theme="Default"/>
  </system.web>
</configuration>

And we'll end up with this nice page:

http://localhost/Cookieless/(S(%7b0861e55a-e29b-4b6f-825b-1e1d4c57f095%7d))/default.aspx

Raw URL /Cookieless/(S({0861e55a-e29b-4b6f-825b-1e1d4c57f095}))/default.aspx
Cookiless Cookies
AspFilterSessionId Request HTTP Header
 
Session ID {0861e55a-e29b-4b6f-825b-1e1d4c57f095}

OOPS! What happened here?

Looks like IIS was unable to transfer the cookies to the appropriate HTTP header but ASP.NET was able to find the requested resource. On the other hand, IIS couldn’t find the http://localhost/Cookieless/(S(%7b0861e55a-e29b-4b6f-825b-1e1d4c57f095%7d))App_Themes/Default/Styles.css.

This happens in these environments:

Operating System IIS ASP.NET
Windows XP Pro SP3 5.1 2.0 SP1, 3.5
Windows Server 2003 R2 6 2.0 SP1, 3.5
Windows Server 2008 7 2.0 SP1, 3.5

Fortunately, in IIS 7 you can have HTTP modules in integrated pipeline mode that are called for every resource requested to IIS.

Your module doesn’t even need to do nothing. It just needs to exist:

public class Module : System.Web.IHttpModule
{
    public void Dispose()
    {
    }

    public void Init(System.Web.HttpApplication context)
    {
    }
}

and be added to the configuration:

<configuration>
  <system.web>
    <sessionState cookieless="UseUri" sessionIDManagerType="SessionIdManager" />
    <pages theme="Default"/>
  </system.web>
  <system.webServer>
    <modules>
      <add name="Module" preCondition="integratedMode" type="Module" />
    </modules>
  </system.webServer>
</configuration>

And our “pretty” page is back:

Raw URL /Cookieless/default.aspx
Cookiless Cookies
AspFilterSessionId Request HTTP Header
S({0861e55a-e29b-4b6f-825b-1e1d4c57f095})
Session ID {0861e55a-e29b-4b6f-825b-1e1d4c57f095}

Is it just me, or there’s something definitely wrong here?

That’s why I opened this bug on Microsoft Connect

Posted Fri, Aug 1 2008 1:23 by Paulo Morgado | 2 comment(s)