C# Multi-Valued Enums [Flags]

February 13th 2008

Ok let me get some Google words happening because I found bits and pieces of this solution all over the place with not one straight answer. So sir Google, this post is about: Multi-Valued enumerators, [Flags], FlagsAttribute, Enums, enum bitwise operations, bla bla bla.
 

So here’s my problem (in case you run into it);

I have few enums in my project. Those include DayOfWeek, MonthOfYear, RecurrenceDay etc. What’s common between those enums is I want to be able to select one, multiple, all or none. So what are  some guidelines to do this?

 

Hmm… ok let’s dig in.

In my case the rules are:

1. Have a None, and All values deified in my enum.

2. Decorate the enum with “[Flags”] to enable bitwise operations.

 

[Flags]
enum RecurrenceDay
{
    None = 0,
    Monday = 1,
    Tuesday = 2,
    Wednesday = 4,
    Thursday = 8,
    Friday = 16,
    Saturday = 32,
    Sunday = 64,
    All = Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday
}

 

Notice that enum have been set to powers of 2 to avoid overlapping of combinations. What do I mean? Since the above is a multiple selection enum you can end up with something like this.

 

RecurrenceDay days = RecurrenceDay.Monday | RecurrenceDay.Saturday | RecurrenceDay.Friday;

 

Which in this case has an int value of 49. Actually the combinations’ values look something like this.

image

to

image

(Now this is a simplistic explanation. Want to get deeper? Read up on the FlagsAttribute and bitwise operations. Otherwise just follow what’s done here and that should satisfy 80% of scenarios)

 

Ok so if I get 49 above, would that help me? most probably not. What I really need is a method that could take in the enumerated value and return an array or collection of the selected values which is exactly what the following method does.

public static Collection<RecurrenceDay> GetSelectedDays(RecurrenceDay days)
{
    Collection<RecurrenceDay> selectedRecurrenceDays = new Collection<RecurrenceDay>();

    if ((RecurrenceDay.Friday & days) != 0)
    {
        selectedRecurrenceDays.Add(RecurrenceDay.Friday);
    }

    ///
    ///
    ///

    if ((RecurrenceDay.Thursday) != 0)
    {
        selectedRecurrenceDays.Add(RecurrenceDay.Thursday);
    }

    return selectedRecurrenceDays;
}

 

Now while the above method works I have 2 problems with it. One can be solved easily and that is the enumerator value ‘All’ will always be returned. Secondly the method is just not generic enough. Every time I have a different multi-value enum I will end up with a new method, plus too many if statements is not my favourite coding habit. So I came up with the following generic method that I think will be helpful if you ever run into this scenario.

 

public static Collection<T> GetSelectedEnumValues<T>(T intputValue, T? allValue)
            where T : struct
{
    Type enumType = typeof(T);
    if (!enumType.IsEnum)
    {
        throw new ArgumentException(typeof(T).ToString() + ” is not an Enum.”, “T”, null);
    }

    //Get all the values of the enumerator
    Array enumValues = Enum.GetValues(enumType);

    //Instantiate collection of T
    Collection<T> output = new Collection<T>();

    //Iterate all values of T 
    //Filter out all methods that are selected using ‘&’
    //Also filter out the ‘All’ enumerator if it’s not null
    foreach (T enumValue in enumValues)
    {
        if ((Convert.ToInt32(enumValue) & Convert.ToInt32(intputValue)) != 0)
        {
            if (allValue.HasValue)
            {
                if (!enumValue.Equals(allValue.Value))
                {
                    output.Add(enumValue);
                }
            }
            else
            {
                output.Add(enumValue);
            }
        }
    }

    return output;
}

 

So now I can use the method above in something like the code below, allowing me to iterate through the selected enums.

 

static void Main(string[] args)
{
    RecurrenceDay days = RecurrenceDay.Monday | RecurrenceDay.Saturday | RecurrenceDay.Friday;

    foreach (RecurrenceDay day in GetSelectedEnumValues(days, RecurrenceDay.All))
    {
        Console.WriteLine(day.ToString());
    }

    Console.ReadKey();
}

 

Which gives me the result of

image

Now sometimes you don’t have an ‘All’ enum. In that case you just pass null to the method for the ‘allValue’ parameter.

Happy Enumerating!

 

P.S. Just wanted to say thank you to Ducas Francis & Tim Sadler who when I went to with this problem they assisted by the very enlightening answer “GOOGLE IT!”. Thanks guys. It really did help :)

 

Also thanks to Paul Stovell for reviewing the code and acting as my “Human Unit Test”

 

UPDATE:

So After talking to Marc Riday he pointed out some nice tips. Using Marc’s tips and some refactoring the final result is.

/// <summary>
/// Constructs a collection of selected enums out of 
/// a multi-value enum (one using the FlagsAttrbute).
/// <remarks>
/// The method will do the following:
/// 1. Check if T is an enum and throw an argument 
///    exception if it is not.
/// 2. Iterate through the list of possible values 
///    of the enum and check it against the passed 
///    in value.
/// 3. If a ‘None’ value exists and no matching 
///    enum is found then a check will be done 
///    to return the ‘None’ value.
/// </remarks>
/// </summary>
/// <example>
/// A typical enum used with this method.
/// [Flags]
/// enum RecurrenceDay
/// {
///    None = 0,
///    Monday = 1,
///    Tuesday = 2,
///    Wednesday = 4,
///    Thursday = 8,
///    Friday = 16,
///    Saturday = 32,
///    Sunday = 64,
///    All = Monday | Tuesday | Wednesday | Thursday | Friday | 
///    Saturday | Sunday
/// }
/// </example>
/// <typeparam name=”T”>Generic type of the enum.</typeparam>
/// <param name=”enumInputValue”>The selected enums value.</param>
/// <returns>A collection of selected enums.</returns>
public static Collection<T> GetSelectedEnumValues2<T>(T enumInputValue)
    where T : struct
{
    Type enumType = typeof(T);
    if (!enumType.IsEnum)
    {
        throw new ArgumentException(enumType.ToString()
            + ” is not an Enum.”, “T”, null);
    }

    Array enumValues = Enum.GetValues(enumType);
    long inputValueLong = Convert.ToInt64(enumInputValue);
    Collection<T> enumOutputCollection = new Collection<T>();

    foreach (T enumValue in enumValues)
    {
        long enumValueLong = Convert.ToInt64(enumValue);

        if ((enumValueLong & inputValueLong) == enumValueLong
            && enumValueLong != 0)
        {
            enumOutputCollection.Add(enumValue);
        }
    }

    if (enumOutputCollection.Count == 0 && enumValues.GetLength(0) > 1)
    {
        T enumNoneValue = (T)enumValues.GetValue(0);
        if (Convert.ToInt64(enumNoneValue) == 0)
        {
            enumOutputCollection.Add(enumNoneValue);
        }
    }

    return enumOutputCollection;
}

Posted by Omar Besiso under .NET & Developers | 9 Comments »

TFS - Third Party Controls

February 12th 2008

The concept is quite simple. Our goal is to get our projects to be self sufficient, stand alone, “build-able” projects.So at any stage I want to check in source files, TFS queues up a build and off it goes. While this sounds sweet, most of projects nowadays have some form of dependency on third party components. which introduces a minor complexity in the way we handle the setup of our projects. Examples of such components might be: Infragistics, Telerik, Xceed, Enterprise Library, AjaxControlToolkit, etc.

The complexity introduced is based on the fact that components referenced from the GAC or a file share somewhere are not actually part of the project. They’re used at run time from their referenced locations. When a build occurs in TFS it fires up assuming it’s got all the components it needs. That’s not true in this case, because the GAC on the TFS build server will not have my third party components (at least it better not!)

So what are some of the things that might go wrong:

  1. The build fails due to not being able to locate third party components on the build server.
  2. The build fails because it can’t locate a license file for the components.
  3. The developers end up with discrepancies over components used. For example one developer might be using ThirdPartyComponent.dll with build number 1256 & another using build 1257. This can happen because source control is not actually governing the referenced components in this case.

 

SIMPLE TIPS ON HOW TO SETUP PROJECTS TO USE THRID PARTY CONTROLS

Ok so I start with the following simple project.

 

image

 

So in my project it has been decided to use infragistics suite and Enterprise Library 3.1. The first step would be to create a dependencies project folder (This can also be a solution level folder if the dependencies will be used across projects. I tend to avoid this if I can).

 

image

 

Next I add all the dlls I need to that dependencies folder.

 

image

image

 

Ok so I have my dependency dlls in a “Dependencies” folder and now I add a reference to the dlls I have added in the dependencies folder.

 

image

 

 image

 

image

This way my dependencies folder is the “source of truth” in the project. I don’t care if hotfixes, updates are applied to the GAC or anything else. The dependencies folder will be checked into TFS and from there onwards all the developers on the team will be sharing the same set of dlls.

 

Now the other problem is licensing. When you fire up the designer of an app and add a third party component on it (such as infragistics) you end up with a license file like the licenses.licx file below.

 

image

 

Now if I check in the project as it stands here and it breaks the build with an error “Cannot locate the license file”. Mmmm…. but the license file is checked in. Now without going into much details how the .NET framework handles these license files, the simple solution is simple.

DON’T CHECK IN THE LICENSE FILE, that’s it.

 

 image

Disclaimer: while the practice above is sufficient for most third party controls I did run into some scenarios where the third party vendor would require some extra steps to get the build up and running. For such instruction please refer back to the vendor’s support team, and go and pray they answer before 2015 :)

 

HAPPY BUILDING!

Posted by Omar Besiso under General | 1 Comment »

Drop that "Add Web Reference" Stuff

February 7th 2008

People have been asking me forever about this and at last I got out of my laziness to actually post it. If you are familiar with Reporting Services then you should also be familiar with the RSExplorer sample application it comes with. My post is not about Reporting Services or RSExplorer but one class in the RSExplorer project called ReportingService2005.cs. This class is actually a proxy class used to call the report server’s web service. Here are snippets from the class.

 

//——————————————————————————
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:2.0.50215.312
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//——————————————————————————

// 
// This source code was auto-generated by Microsoft.VSDesigner, Version 2.0.50215.312.
// 
namespace Microsoft.SqlServer.ReportingServices.ReportService2005
{
    using System.Diagnostics;
    using System.Web.Services;
…
…
…
/// <remarks/>
        public ReportingService2005() {
            //this.Url = .Properties.Settings.Default.WindowsApplication1_ReportService2005_ReportingService2005;
            if ((this.IsLocalFileSystemWebService(this.Url) == true)) {
                this.UseDefaultCredentials = true;
                this.useDefaultCredentialsSetExplicitly = false;
            }
            else {
                this.useDefaultCredentialsSetExplicitly = true;
            }
        }
…
…
…
public new string Url {
            get {
                return base.Url;
            }
            set {
                if ((((this.IsLocalFileSystemWebService(base.Url) == true)
                            && (this.useDefaultCredentialsSetExplicitly == false))
                            && (this.IsLocalFileSystemWebService(value) == false))) {
                    base.UseDefaultCredentials = false;
                }
                base.Url = value;
            }
        }

 

Well this is handy. So instead of adding a web reference to a project wouldn’t it be nicer to have a class where I pass the url to the constructor to instantiate my web service object. So in the above code the SQL team used Microsoft.VSDesigner to generate the class. Now Microsoft.VSDesginer is a dll involving a lot of COM operations under the hood, it’s not documented and doesn’t have the most intuitive API to work with. Now if you go through the class you’ll notice it is actually almost identical to what our old friend “wsdl” generates.

 

So here goes, I create my super Hello World Web Service.

 

image

 

I have this test console app and normally you would go and add web reference doing the following:

 

image

image

 

image

 

Now you can instantiate the web service as you please by doing the following.

ConsoleApplication1.localhost.Service1 svc = new ConsoleApplication1.localhost.Service1();
svc.Credentials = System.Net.CredentialCache.DefaultCredentials;
Console.Write(svc.HelloWorld());
Console.ReadKey();

 

You can even control the url of the service in your config file since an entry has been automatically created for you (But why in settings?? aaargh).

<applicationSettings>
        <ConsoleApplication1.Properties.Settings>
            <setting name=”ConsoleApplication1_localhost_Service1″ serializeAs=”String”>
                <value>http://localhost/HelloWordWebService/Service1.asmx</value>
            </setting>
        </ConsoleApplication1.Properties.Settings>
    </applicationSettings>

 

But this is not the behaviour I am looking for. I simply want a class that I instantiate with the url of the Web service and from there onwards I can use the instance of that class to call the web service methods I need, and I am also sick of setting the default credentials after I instantiate the service so let’s make the assumption I will be using default credentials all the time. So let’s take the following simple steps to achieve that.

 

1. Use the wsdl command to generate your proxy class.

image

 

2. Import that file into your solution (I removed the web reference from before for clarity).

 

image

 

3. Manually change the constructor of the class.

 

FROM

public Service1() {
        this.Url = “http://localhost/HelloWordWebService/Service1.asmx”;
    }

 

TO

public Service1(string myUrl) {
        this.Url = myUrl;
        this.Credentials = System.Net.CredentialCache.DefaultCredentials;
    }

 

4. Praise your new calling code.

            Service1 svc = new Service1(“http://localhost/HelloWordWebService/Service1.asmx”);
            Console.Write(svc.HelloWorld());
            Console.ReadKey();

 

NOTE: With this approach every time you update your webservice or service reference remember to update the constructor’s code. You can also leave the default constructor in there and add your own constructors as overloads for any more advanced needs. That way you can instantiate the object and initialising internal variables to whatever your heart desires but still keeping the default behaviour.

As you see my project is much cleaner and I have no dependency on a config file anymore. Now usually I do advise people to keep the url in the config file anyway but removing it from the settings file. Also who knows one day you might need to pull the url of the service from a text file or a database.

 

Hope this was useful.

HAPPY CODING!

Posted by Omar Besiso under General | No Comments »

TFS2008 Build Error (LC.exe)

February 2nd 2008

Well the error is as follows when a build runs on the server:

C:\WINDOWS\Microsoft.NET\Framework\v3.5\Microsoft.Common.targets(1734,9):
error MSB3091: Task failed because “LC.exe” was not found, or the correct Microsoft Windows SDK is not installed.
The task is looking for “LC.exe” in the “bin” subdirectory beneath the location specified in the InstallationFolder value of
the registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v6.0A. You may be able to solve the problem by doing one of the following: 
1) Install the Microsoft Windows SDK for Windows Server 2008 and .NET Framework 3.5. 
2) Install Visual Studio 2008. 
3) Manually set the above registry key to the correct location. 
4) Pass the correct location into the “ToolPath” parameter of the task.

So the only thing which seemed to work is re-installing the SDK again. It can be found here.

http://www.microsoft.com/downloads/details.aspx?FamilyId=74DD6E2D-89C6-4E1E-AF00-FC7D70F15439&displaylang=en

Posted by Omar Besiso under General | 1 Comment »

TFS 2008: Projects Binding Bug

February 2nd 2008

Had a strange behaviour today. After binding a solution to TFS 2008, on re-opening the solution it looks like all the binding is gone. Well it really isn’t. What’s happening is it’s opening the solution in offline editing mode. This happens when the TFS instance goes offline. This appears to be a known bug in TFS 2008 that will be fixed in Service Pack 1. The solution is quite simple though. All you have to do is right click your solution and click on “Go Online”.

More detailed example here:

http://gabriel.lozano-moran.name/blog/PermaLink,guid,40ec1818-1e8a-45de-9111-7370544d3ba4.aspx

 

Happy TFSing!

Posted by Omar Besiso under General | No Comments »

My Answer to Mitch’s XYZ Framework Questions

January 31st 2008

     Let me say it out loud. I like Mitch’s brain. It’s a phenomenon. It’s vocal, smart, sharp and way outside the box. But you know what else Mitch is ?????? Passionate. Passionate about his ideas, his beliefs and his visions. Now while this might seem like a paid post to make Mitch look good, it isn’t. Mitch posted some questions as guidelines on using *frameworks*.  This is me wanting to take Enterprise Library as an example and trying to answer Mitch’s questions in a very very objective manner.

 

Does it make it more complex than it needs to be?

 

Well internally it definitely is. It’s one monolithic object model that most probably I wouldn’t sit and code myself to solve all the business problems that my projects would face in the unknown future. *But* remember who their clients are. The .NET community. What the P & P team are trying to achieve is solve most of the *common* problems that face about 70% of the developers on daily basis. Data Access, Exception Handling, Logging. They’re trying to sit in the common components layer of every model. Is that Bad?

Yes, because Enterprise Library becomes the framework that people use while being oblivious of what’s happening under the hood and oblivious to the face that it’s a big dependency. If the requirements become more complex developers start thinking of how to customize their solution around Enterprise library’s limitations instead of coming up with a much simpler solution using the .NET framework as it stands.

No, because if you think Enterprise Library doesn’t add a productivity gain and a high level of abstraction to complexity then I think you should think again.

 

Does it really add any value beyond allowing me to +1 the font size on the “A” on my “Architect” t-shirt?

 

Mitch, just last week, warned me that if I ever become an A-Architect he will hunt me down. So as an architect Mitch, I would use Enterprise Library in some circumstances and not because I want to be the big Architect but somehow we’re not on the same line of realising that Enterprise Library is actually good for some scenarios. Actually I think the main key to the success or failure of an architect using Enterprise Library is knowing when to use it and not to show off that you actually know how to use it and get past that hairy configuration driven approach :).

 

Who is going to support it?

 

Tom Hollander :) . Now if you want a serious answer, who supports all third party components that don’t exist in the framework? The vendor. So if the P & P team aren’t supporting it then no one is (well maybe the open source developers on CodePlex) and you will just have to hope that nothing goes wrong. In their favour though, I haven’t heard of much that goes wrong with enterprise library itself. But that configuration tool, “Oh My!”.

 

Will it impact performance?

 

Well I won’t go into this in detail but when you load the quantum measures into an analysis services cube with measures being Productivity-Performance-Scalability-Reliability and then load EntLib’s data into it and get an answer, please let me know :)

Yes it does. But is the impact significant enough for you not to use it? Does it give you gains to overlook the performance issues?

 

Does it solve a problem that actually exists?

 

Code and business logic solve problems, not frameworks. You build on top of the frameworks to solve problems. Enterprise Library is just another layer of abstraction supposedly in favour of simplicity. It’s not a solution for anything. If you use application blocks just for the sake of it, something is definitely wrong.

 

Could I solve that problem easier with 10 lines of C# code?

 

NO NO NO NO NO. If I have a requirement to use just 10% of Enterprise Library’s functionality then I am definitely saving myself writing more than 10 lines of code. To be objective this differs from one application block to another. So if I am using the data application block without needing to support multiple databases definitely no, but if I am using the validation or policy injection block then definitely it’s saving me way more than 10 lines of code specially on large scale projects.

 

Conclusion

 

I hope I was objective enough Mitch and one thing I do agree with you on is abstraction layers should never become frameworks and in fact there should be a need for an abstraction layer in the first place. But when needed, abstraction layers and utilities (not frameworks) are excellent to have. But you’re right, different views on the same component is where debates start :)

Posted by Omar Besiso under General | No Comments »

Using Sandcastle for the first time

January 31st 2008

      Remember NDoc? Really cool. Only problem is after some conflict (don’t ask me what, just rumours) development has stopped on NDoc and so it doesn’t support any .NET framework higher than 1.1. So long story short I needed to produce a chm file for a library I’ve built and I thought I’d give Sandcastle a try. Now, using the command prompt was a killer but thanks to this “Sandcastle help file builder GUI” things started looking like NDoc again :)

 

image

 

Download Sandcastle here:

http://www.codeplex.com/Sandcastle/Release/ProjectReleases.aspx?ReleaseId=9921

You can download Sandcastle Help File Builder Here:

http://www.codeplex.com/SHFB/Release/ProjectReleases.aspx?ReleaseId=9848

Posted by Omar Besiso under .NET & Developers | 2 Comments »

First Peak at Windows 7

January 26th 2008

Don’t know if this is real but here goes.

 

Posted by Omar Besiso under General | No Comments »

Placing the Pillars (Part II - Preparing My Solution)

January 26th 2008

     People have been asking for the second part of the post thinking that it might be another base class or another entity list that I have been working on. This time things are different. I realised lately that many people don’t realise the power they have with visual studio and how they can use that power to improve the way they work by applying some simple practices. I decided to tell on how I do stuff hoping that I will make you think differently about how you do projects and mostly hoping for some feedback that will help me improve mine. I will be posting few posts until we have a fully running application so please bare with me. I, as usual, will use domain modelling and binding oriented programming all the way so hopefully you find this useful. Please note that this not an architecture post; so some simplistic examples will some times be used to demonstrate the methodology used.

     So for the sake of this post let’s say we have the following scenario.

 

A school will needs to implement a CRUD application that saves information about students. The decision was made that the application will be a windows application accessing a WCF service that take care of validating and persisting data. Why a service and not direct database access? One, for security and Two, in the future iterations of the project we will be implementing Mobile and web clients to the service as needed.

    

     Now I am sitting in my Virtual Office (at home) and I get the above abstract with few other bits of documents outlining some of the information to be saved and some of the validation rules. Why am I using a crud application? For the sake of simplicity only but I will make sure I include a bit of business logic to show how my objects will not be data driven. Surely as a domain modelling advocate I am forced to do this to satisfy thy inner self :).

     So usually the first thing I would do is go and create a team project on TFS but for the sake of this exercise let’s jump straight into Visual Studio. The first step for me is always:

 

CREATE A BLANK SOLUTION.

 

Yes a blank one. Not a web application. Not a windows application. Not a class library. For heaven’s sake just a blank solution. It’s just sensible, you start with the root and start adding different projects as needed.

 

image

 

Notice that my preferred location (although not liked by a lot of people) is my projects folder. Why? Well just easier when using any backup software to grab the entire user folder with music, videos and projects :). I do backup daily (No Really, I do). Also I find the “My Projects” shortcut below pretty handy.

image image

 

In my post “Visualising Software with Diagrams” I spoke about how much I like visualising the solution and the architecture involved in implementing the solution. So what would be my next move?

 

DIAGRAMS, DIAGRAMS, DIAGRAMS (Please not that the following tools are available in Visual Studio Team System for Architects or Team Suite)

 

My favourite one is called the Logical Datacentre Diagram. Using it I can have a very high level diagram of how my application would be deployed after I am done. So for the project in hand I would have the following steps to get to a diagram.

 

image

 

image

image

and my diagram would look something like this.

image

 

By doing this simple exercise I have now at least visualised the high level components of my solution. Now each of these components can represent various things, teams, tiers, and my preferred one, boundaries. Every one of the components above defines for me a logical boundary more than a hardware one. The logical datacentre diagram is not the only diagram in play, for every project I will also create an Application Diagram:

 

image 

and the system diagram that can also encapsulate multiple applications that constitute a global system.

image

 

While Distributed System Diagrams are brilliant for visualising a high level distribution of components, they are also powerful in creating constraints and assigning properties to each one of the components. For example you can assign a connection string to your database from within the diagram itself by using the properties of the external database component. For more detailed info on the DSMs please visit http://msdn2.microsoft.com/en-us/library/ms379624(VS.80).aspx

 

COMMON ITEMS

 

After having some visual in my head now of what the system components are I tend to take 2 steps next.

 

1- Generate a key that I will use to strong name each one of my projects. For the sake of this demo I will create a quick key without actually using a password and I will also use the same key to strong name all of my projects. So using the visual studio command prompt

image

 

2- Include a SolutionInfo.cs file that I would use to define properties that are common among assemblies. This is to avoid having repetitive information in over bloated assemblyinfo files. My Solution info file would look something like this.

 

using System.Reflection;
using System.Runtime.InteropServices;

//General information about the solution
[assembly: AssemblyCompany(“Omar Imaginary Corporation”)]
[assembly: AssemblyProduct(“MySchool”)]
[assembly: AssemblyCopyright(“Copyright © Omar Imaginary Corporation Corporation 2008″)]

// Setting ComVisible to false makes the types in this assembly not visible 
// to COM components.  If you need to access a type in this assembly from 
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Revision and Build Numbers 
// by using the ‘*’ as shown below:
[assembly: AssemblyVersion(“1.1.1.1″)]
[assembly: AssemblyFileVersion(“1.1.1.1″)]

 

As a tip for the assembly version above if you were to replace “1.1.1.1″ with “1.1.*.*” then the build and revision numbers would be automatically generated for you.

So after all the steps above our solution should like this so far.

image

Once you get used to these small practices you’ll find that in you can get all the above done in about 30-45 minutes and yet produce basis on which you can build both thought and code.

 

LAYERING OF MY SOLUTION (This not the same as tiers)

All this means is that I am going to create some solution folders to separate my code logically maintaining yet again some logical boundaries. So for the sake of this example here’s what my solution would look like.

 

image

 

SERVER DOMAIN MODEL

Since in this post we’re not concentrating on code let’s say i start by creating a domain class library on the server side just to show how do I get my projects ready.

 

image

 

Now before doing anything 2 things are essential here.

1- Add a link to the SolutionInfo file I created earlier and adjust the AssemblyInfo.cs of the class library.

image

 

image

For cleanliness move solutioninfo.cs link into the properties folder of the project with my AssemblyInfo.cs which now looks like this.

image

using System;
using System.Reflection;
using System.Security.Permissions;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;

// General Information about an assembly is controlled through the following 
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle(“MySchool Server Domain Model”)]
[assembly: AssemblyDescription(“Domain Model of the MySchool Application”)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid(“92f4d02c-4cb2-4d7f-b811-5fcb0b7b0258″)]

//Added to make assembly CLSCompliant
[assembly: CLSCompliant(true)]

 

Notice that the AssmblyInfo file now is much smaller because we moved the common entries into SolutionInfo.Also notice that I marked the Assembly as CLSCompliant. I will show later how I run FxCop on every single project so I can make sure I am complying with all microsoft’s performance and design rules. One of the first rules ofcourse is making the assembly CLSCompliant and you can read more about that at http://msdn2.microsoft.com/en-us/library/bhc3fa7f.aspx

2- Add a link to the key I created earlier so I can strong name my assembly.

Again I add a link to my key on place it in the properties directory.

image

Now I sign my assembly and notice that my key appears in the key options because already exists in the solution and is linked to in my project.

image

Now my assembly will be signed. One thing to note here is that the reference to the key in the project file is relative. So if you require a different behaviour you need to modify the project file. Here are the key tags you need to worry about in your csproj file.

<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>..\MySchoolKey.snk</AssemblyOriginatorKeyFile>

<ItemGroup>
    <Compile Include=”..\SolutionInfo.cs”>
      <Link>Properties\SolutionInfo.cs</Link>
    </Compile>
    <Compile Include=”Properties\AssemblyInfo.cs” />
  </ItemGroup>
  <ItemGroup>
    <None Include=”..\MySchoolKey.snk”>
      <Link>Properties\MySchoolKey.snk</Link>
    </None>
  </ItemGroup>

 

The steps I have taken here are the steps I am going to follow every time I add a new project to my solution before starting any code.

Now I am ready to design / code my domain. See you in the next post.

Posted by Omar Besiso under .NET & Developers | No Comments »

ASP.Net XHTML Validation and Framesets

January 24th 2008

I was going through some old code today to bring it in to Visual Studio 2008. One of the pages in the system used a frameset.

Under Tools / Options, I had HTML Validation set to Transitional.

clip_image002

When you add a new aspx page it validates your HTML against this schema by default.

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”

http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd“>

 

But the value inserted into your page actually comes from the web form template, not by changing the above option. The templates are usually found in  Program Files \Microsoft Visual Studio 9.0\Common7\IDE\ItemTemplatesCache\Web\CSharp\1033\ (or VB’s location).

Any errors you have in your markup are underlined and come up as warnings or messages in your Error List tab in Visual Studio.

XHTML does support framesets but the following markup

 

<head>
<title>My Page</title>
</head>
<frameset cols=”180,*”>
    <frame frameborder=”0″ marginheight=”0″ marginwidth=”0″
    id=”frameNav” noresize=”noresize” scrolling=”no” src=”Navigation.aspx” />
    <frame frameborder=”0″ marginheight=”0″ marginwidth=”0″
    id=”frameMain” noresize=”noresize” scrolling=”no” src=”Main.aspx” />
</frameset>
</html>

 

produced errors on almost all tags, such as - Element ‘body’ occurs too few times, Element ‘frameset’ is not supported and so on.

Yet the syntax is correct – you cannot have a body tag AND a frameset in the same page, so to suggest the body element occurs too few times is not correct.

I found that I had to change the validation to XHTML 1.0 Frameset.  Then I could validate and fix any frameset errors.

clip_image002[5]

For correctness I placed this schema on the page, as it will get generated back to the browser.

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Frameset//EN” http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd“>

 

You could submit this page with the frameset for validation under Firefox and it will use the frameset.dtd schema.

clip_image002[7]

Of course this now invalidates all other pages. Apparently Visual Studio allows one schema of validation for the whole website, it cant really be set at page level (that would be nice).

So if you are using frames in older systems (newer ones may look towards CSS styles applied to the div element), you can do a quick validation via the change in the Tools / Options HTML Validation setting, but then I suggest you switch it back again to another schema. Normally only one page in your web app  will contain the frameset.

If you ever have the page with the frameset open when you compile, just ignore the warnings. You know better.

Posted by Omar Besiso under .NET & Developers | 2 Comments »

Next »