Showing posts with label Visual Studio. Show all posts
Showing posts with label Visual Studio. Show all posts

Tuesday, 19 June 2012

Asp.net MVC 4 WebAPI RC - What on earth is “Antlr3.Runtime”?!

I upgraded to the latest version of Asp.net MVC 4 at the weekend which is the newly released “RC” so thought I’d have a play and see what’s changed.

On doing File > New on a new MVC 4 / Web API project a newly clean crisp solution loads up in Visual Studio. Just out of interest I make sure it builds – can’t be too careful with these “pre-release” builds. The solution builds fine so it’s time to explorer …

I expand the project references to see what dependencies the project now has and the list is quite large. The usual suspects are there; EntityFramework, System.Web.Mvc, System.Web.Razor etc. but I’m greeted by some un-usuals.

Disclaimer: I’ll point out now I didn’t do this check on the Beta so I’m not sure if some of the following where there before.

The first one is new and expected; Newtonsoft.Json. We’ve been hearing for a while that json.net will be rolled into the final release and here it is. Nice! I’ve been using json.net for other projects for a while and it’s good.

The second two which seem out of place are “Antlr3.Runtime” and “WebGrease”. What on earth are these?

Lets look at WebGrease first …

  • It has an entry in the nuget package file with a version number etc.
  • In object browser it has some of the “Microsoft.Ajax.Utilities” namespace in.
  • The rest seems to do with css, ui etc.
  • Delete it and the app still builds and runs.

Guessing can live with that, but could remove it. What does it do?!

The other remains a mystery; “Antlr3.Runtime”.

  • No entry in the nuget packages
  • Remove it and the default app still builds
  • In object browser from the class names it looks like it does something with Tree structures?!

From doing some searching it relates to parsing grammers etc. to interpret them in your application. Why would that be shipped with asp.net mvc 4? Couldn’t find any documentation to support this so maybe it was an oversight and will be removed from the final RTM version. Will have to wait and see …

Wednesday, 17 March 2010

SqlParameterCollection Extension Method AddWithValue

I don’t know why it’s not included in .net 3.5 / c#3 but the recommended way of adding a SQL Parameter to a SqlParameterCollection is to use the AddWithValue method; however, you can’t specify the SqlDbType with any of the overloads. It’s not hard …

    public static class DataAccessExtensions
{
/// <summary>
/// AddWithValue specifiying the <see cref="SqlDbType"/> of the parameter
/// </summary>
/// <param name="collection">The collection to add the parameter to</param>
/// <param name="parameterName">The name of the parameter</param>
/// <param name="value">The value of the parameter</param>
/// <param name="sqlDbType"><see cref="SqlDbType"/> which the SqlCommand is expecting for the created parameter</param>
public static void AddWithValue(this SqlParameterCollection collection, string parameterName, object value, SqlDbType sqlDbType)
{
var result
= new SqlParameter(parameterName, sqlDbType) { Value = value };
collection.Add(result);
}
}



Wednesday, 3 March 2010

Asp.net MVC – When to use strongly typed ViewData?

In short; all of the time unless you have a *really* good reason not to.

With the use of generics being able to specify a strongly typed model per view / partial view is so easy with the baked in functionality in the framework, so why aren’t you using it?

Why?

The whole point of MVC is to have control over markup, enable specific routes and reuse existing views / partial views in different locations among others. It’s not to make your life harder than it already is. The underlying issue is if you don’t have the a strongly typed view model for each view then you don’t have confidence in having complete control over it. Throw in a dev team, potentially, changing the same weakly type code and you’re looking for pain.

When you first start looking at examples of MVC applications, you find examples where people start putting in values in to the ViewData dictionary which is available on the views/controllers.

ViewData["MyKey"] = "Some string value";



This uses the weakly typed ViewDataDictionary which can lead to issues with keys not being present, casting it to the wrong type (potentially) and can lead to unnecessary complexity beyond what is required. This can create hard to maintain spaghetti code in the view markup (can anyone say “classic asp 3” ?) … all of which is bad.




So are you suggesting a ViewData model class per view?




Yes; this is exactly what I’m suggesting. This leads to well structured solutions and keeps the code and views together. This isn’t such a big problem when working on your own, but if you know the system you are writing will be a lot bigger when completed or you work in a bigger team (or both) then it’s better to keep things as simple and clear as possible as early as possible. Set a good foundation to work from.





So my current Visual Studio project layout looks something similar to this :



image 



The view data class definitions and the associated full / partial views are filed away in similar namespaces / folder structures * underneath their associated areas of the solution so that you know which are linked together more easily.





* The views in this case are filed under Document instead of Documents because of the name of the controller, although are potentially incorrectly named  :-)




Summary

So to summarise, why do this? Well it helps to know what you’ve got to play with in each view. It breaks down the specifics which you need to pass into a view/partial view to get it to operate nicely. It also means when re-using partial views you know what to pass into them. Also, with strongly typed goodness it helps with refactoring especially when using tools such as Resharper.





Let me know your thoughts.


Further reading:

MikesDotNetting - ASP.NET MVC Partial Views and Strongly Typed Custom ViewModels

Thursday, 4 February 2010

Best error message … Ever!

I’ve had a few good error messages in my time, but waiting for something I am debugging at work to time out I just received the following message:

image

Nice!

Edit: Found a useful Stackoverflow answer to help resolve this issue.

Tuesday, 26 January 2010

Migrating Team Foundation Server 2010 Beta 2 to new servers

Disclaimer : It worked for me, and I hope it works for you, but do so at your own peril. Make sure everything is backed up and I’d suggest testing on a spare machine first before doing it for real.

We’ve been looking at changing our infrastructure at work and moving from VMWare for our virtual servers to using Windows Server 2008 and Hyper-V. The main server which needed to be moved/converted/migrated between the two different virtualisation technologies was the TFS Server; and hence my domain.

I started off by trying to convert the vmdk file to a vhd file which seemed to work well and could be mounted and the data on it read. However; I was unable to boot from it. After spending, way, too much time trying to get it working I decided to look at the migration exercise. And to be honest it was essentially a disaster recovery exercise as we’d have to go through the same steps if it all went wrong so the time wasn’t wasted.

So after doing a test run on a spare virtual machine we had before the server was taken down I fired up the install for SQL Express and started on the path to setting up TFS. After doing some Googling, and finding loads of different articles which seemed to do bits but not all of it I thought I’d post my findings to hopefully help someone in the future. These are the steps which I came up with. I have also now deployed TFS into the new virtualised production system and it seems to work fine (not got automated builds working yet tho).

Here we go:

  1. Backup databases from old TFS. This includes the Tfs_Configuration databases and any project collection databases.
  2. Build/patch new VM with Windows Server (or other OS)
  3. Install SQL Express 2008 with tools
  4. Restore databases, with the same names, into your new SQL Server instance
  5. Install Team Foundation Server 2010 Beta 2 (and reboot when required)
  6. Run the following command – making sure that you have the correct details in the right places

    c:\Program Files\Microsoft Team Foundation Server 2010\Tools>tfsconfig accounts /add /accountType:applicationTier /account:"NT Authority\Network Service" /sqlInstance:.\SqlExpress /databasename:tfs_configuration
  7. Create a local user named after the server name. So for example if your server is called “TFS” then create a local user called “TFS$” (without quotes)
  8. Fire up the Team Foundation Server admin, go to configure installed components and run the Application Tier only upgrade wizard
  9. Once in the wizard point it to the SQL instance locally and it should find the configuration database, select it and continue.
  10. Finish the wizard and it should be pretty happy. Next thing to do is update the server urls on the main server details page to point to the new server name (as it’ll have the old server name in it)
  11. Start up the project collection(s) and throw in a server restart for good measure.
  12. Done!

You should now be able to connect to the server through Visual Studio as before. You will need to add in the new server details (and remove the old). I found all the workspaces where fine and all was good to go.

With a big team its probably wise to get everyone to shelve all their changes over a weekend or evening and make sure nothing is checked out. But this is down to preference and may need to be tested.

Hope this helps someone in the future :-)

Thursday, 7 January 2010

Map network drive in code

I needed to programmatically map a share drive to access files for a asp.net web application. This works on the app pool identity and doesn’t have mapped drives by default so after a little Googling, I found this :

http://www.codeproject.com/KB/system/mapnetdrive.aspx

It maybe a few years old, but works like a dream!

Tuesday, 1 December 2009

WCF and serializing custom objects

I’ve been setting up an wcf service for a new n-tier system which I am currently architecting and developing at work. I’m trying to get to the point where all tiers store the data in the same objects (Entities) and they are worked on at different levels. These are simple POCO Entity objects which only store the data values and defined the data annotations to be used with validation. This will require the WCF service to be able to serialize the custom objects and transmit them between the tiers and in future, who knows maybe to a Silverlight client application as well?!

So, with the objects in place and with the correct DataContract and DataMember attributes in place I get the following error message when trying to pass them through the service between tiers:

“The underlying connection was closed: The connection was closed unexpectedly.”

After doing some Googling I came across the following blog post which had some handy pointers … thanks Bishoy Labib. But the biggest help was from a post by Damir Dobric. His post explaining how the "KnownTypeAttribute” is used when sending through data over a wcf service was very handy.

So after decorating the interface with each type of Entity I had which (3 so far) I built the project, got the service reference to update to get the latest definition and ran it with fingers crossed … it worked!

Damir had adding each of the types which might be used through the WCF service interface defined individually, then refactored it by adding them through the KnownTypeContainer (similar to below) and added them manually. This wouldn’t quite work for me as there are going to be, probably, lots of entities and I don’t want to have to add one individually each time. As all the entities are defined in a single project, I thought with a little reflection on the Assembly I could dynamically load them in so came up with this …

[ServiceKnownType("GetAllMyKnownTypes", typeof(KnownTypeContainer))] 
[ServiceContract(Namespace
= "http://mynamespace/2009/IApplication")]
public interface IApplication
{
[OperationContract]
string Echo(string value);

[OperationContract]
Entities.EntityBase Execute(
string action,
Dictionary
<string, object> parameters);
}

static class KnownTypeContainer
{
public static IEnumerable<Type>
GetAllMyKnownTypes(ICustomAttributeProvider p)
{
return new List<Type>(
Assembly.Load(
"Entities").GetTypes()
);
}
}




Nothing special, or clever, just need to make sure that all the Entities derive from the common EntityBase abstract class to work.



Thanks go to Damir for the original post and getting me through my issue I was having :-)

Wednesday, 18 November 2009

Smtp4dev

Ever had to setup a local SMTP server when you’re developing some functionality but don’t want the emails being sent out by accident?

I’ve had a couple of systems which I’ve written over the years and been a little paranoid each time that some test emails will be sent out to a live email address. This stems from a project I worked on a while back and had to send the system to the company development team so they could do some in depth testing/debugging and they ended up sending over thousand emails out to the client ;-)

Any how …

I went to setup an SMTP server locally to do some testing today and found out that Windows 7 doesn’t have a built in SMTP server option anymore so went on a Google hunt. After doing some searching I came across a few free server options, but the one which caught my eye was on Codeplex. My initial thought was “Woo, can see how they wrote it if I want to” and the description was spot on …

Project Description
Dummy SMTP server that sits in the system tray and does not deliver the received messages. The received messages can be quickly viewed, saved and the source/structure inspected. Useful for testing/debugging software that generates email.

Anyway, I downloaded the latest build of smtp4dev as it seemed to fill all my requirements; a) does not deliver email and b) doesn’t interfere with anything else. 

The description was spot on, and so far so good it works as required. Will post an update once have used it a bit more.

Hope it helps others out in the future. Let me know if this helps you!

Asp.Net MVC 2 Beta released

After checking my morning blog feeds the first one in the list which was of interest was Phil Haack’s post about the release of Asp.Net MVC 2 Beta for VS 2008. I was going to put off downloading it and updating until later but after the teaser about nuclear facilities in the Eula I had to investigate …

This was the full Use rights which he was referring to:

a. Because the software is a pre-release version, and may not work correctly, you may not use it, alone and/or in conjunction with other programs in hazardous environments requiring fail-safe controls, including without limitation, the design, construction, maintenance or operation of nuclear facilities, aircraft navigation or communication systems, air traffic control, and life support or weapons systems.

I should read EULAs more often; Genius!

Tuesday, 10 November 2009

Windows 7 Aero snap shortcuts

I was browsing through my regular blog feeds this morning and the tweets which had happened over night this morning and I came across the following link. It’s posted in the context of Visual Studio 2010 Beta 2, however it works for any window which is currently selected.

As I use a duel screen setup at work and manually dragging/snapping the windows to the side of the screen only work at the far edges of the entire desktop real estate these short cuts enable halving both screens spot on.

The short cuts which are starting to be high up on my most used list are:

Dock to Screen Left : Windows + Left Arrow
Dock to Screen Right: Windows + Right Arrow

I’m lovin’ Windows 7!

Monday, 9 November 2009

Have people not heard how to use namespaces?!?!

I’m trying to work out how something works and it’s over mulitple dlls. This is fine in the grand scheme of things. They aren’t large dlls either and the names of them gave me hope that it would be well designed. One has the data access code, one with common code and one with the business rules. Three projects working together isn’t large at all. I’ve worked with Visual Studio solutions with almost 100 projects in, so how hard could this be … ?!

So far so good …

That was until I started looking at the names of the class definitions. This is the point when I wanted to bang my head on the desk!

In the data access dll, it has a data access namespace, yet all the class definitions are prefixed with ‘dal’.

Why?!

In the business rules dll, it has a business rules namespace, yet all the class definitions are prefixed with ‘br’.

No seriously, why?

And to top it all off, the data entities are in the the 3rd dll, all post fixed with ‘Data’ … this in itself isn’t bad, except the namespace is ‘Data’ so that kinda makes the post fix redundant.

And don’t get me started on the name of the dll … and no it doesn’t even have the word ‘data’ in it (see the opening paragraph ;-))

Why would you do that?!?!

*hithead*

Wednesday, 4 November 2009

Visual Studio 2010 Beta 2 initial thoughts

Just thought I’d post a small brief entry about my initial thoughts of Visual Studio 2010 Beta 2. So far so good I like it, the layout is nice, the tooling improvements are good, the response speed of the IDE has improved quite a lot … however, I won’t be using it full time until there is a version of Resharper which works with it; I’m lost without the R# power!

:-)

Tuesday, 27 October 2009

TFS 2010 Beta 2 unit testing automated builds

I’ve been setting up Team Foundation System 2010 Beta 2 at work over the past couple of days. First starting off with doing it on a virtual machine locally to do some testing, but then deploying it into the virtual server environment we’ll be using it in for every day development.

I was initially very impressed by the ease of setup of the system. Talking to people and ready some blogs about setting up previous versions of TFS it was a complete pain with caused serious issues with server setup, permissions etc. TFS 2010 is soooo simple in comparison. Microsoft have thought about this side of things a lot and made setting it up very simple.

We went for the basic setup as we don’t need a lot of power or more than source control, automated builds and work item tracking.

Anyway, setup of the machine was fine and enabling communication between the tfs server and my laptop running Visual Studio 2008 sp1 was fine (just needing to make sure that Team Explorer is installed, followed by running the VS SP1 setup again, then the forward compatibility patch) and the first solution of code was checked in. A small utility dll project and associated unit test project. As the plan is to use this utility in all future development, a “tool kit” as you would, it made sense that this should be setup to have an automated build. It would also enable me to learn how to setup automated builds.

Enter first issue, no reference issues relating to “Microsoft.VisualStudio.QualityTools.UnitTestFramwork.dll”. Due to this issue the test project could not build as it had references to a namespace it couldn’t find.

C:\Windows\Microsoft.NET\Framework64\v3.5\Microsoft.Common.targets: Could not resolve this reference. Could not locate the assembly "Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL". Check to make sure the assembly exists on disk. If this reference is required by your code, you may get compilation errors.

To resolve this initially I installed the C# components of Visual Studio 2010 Beta 2 on the server. I had originally just done the unit testing parts but this didn’t resolve the issue. The obvious issue with this is that we don’t want to have the full version (or any part of) Visual Studio installed on the server so I did this on a VM locally to see if resolved the issue … it didn’t :-(

Break through

After doing some more search on Google, I found this post from Grumpy Wookie about the location of the gacutil in the SDK, and another link (which I can’t seem to find in my history, sorry) relating to the fact that there aren’t the correct versions installed in the GAC on the server. So after checking the versions and seeing there weren’t any there …

I copied the following dll from my dev machine (with VS2008 on):

Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll

To

C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5

I then opened a cmd prompt on the server and navigated to where the SDK resides and ran the following cmd:

C:\Program Files\Microsoft SDKs\Windows\v7.0\Bin>gacutil.exe /i "C:\Program File
s (x86)\Microsoft Visual Studio 9.0\Common7\IDE\PublicAssemblies\Microsoft.Visua
lStudio.QualityTools.UnitTestFramework.dll"

This loaded version 9 of the UnitTestFramework into the GAC. This allowed for the automated build to run and to run the unit tests in my solution. Only issue now is the fact that it seems to be running with v10 MSBuild/MSTest with the v9 unit test assemblies and because of that it doesn’t like the one test which is using the ExpectedExceptionAttribute. At the moment I can live without this test being run on the server … but roll on march when the full version of TFS/VS 2010 come out and I can upgrade my development environment.

Hope this helps.

Visual Studio 2008 + IIS 7 development

At my new job part of my role is to bring most of the current website development in house for the 8 websites we currently have. Due to this I have decided to instead of just run them on the built in development web server which ships with Visual Studio and launches when you hit f5 with an address something similar to http://localhost:58697/Website1 to setup individual websites in IIS to best replicate the production environment. This is possible as IIS 7 on Windows 7 allows multiple websites on the client OS.

To do this I did the following:

1. Create a new website in iis 7 manager console; setting the host name to <identifier>.localhost

image

2. Update the hosts file to point the local loop back ip address to know about this new host name. Open the hosts file found in C:\windows\system32\drivers\etc\ and add the following line:

127.0.0.1                         website1.localhost

3. Open the Visual Studio solution (as Administrator) with the website in and navigate to the property page of the website. Navigate to Start Options > Server > Use custom server and set the Base Url to http://website1.localhost

image

4. Hit f5 in Visual Studio and run it.

I hope this helps anyone looking to do a similar thing.

Enjoy :-)

Tuesday, 27 January 2009

Accessing object properties from string representations

Late last week I was looking into sorting a custom POCO (Plain Old CLR Object) collection which derived from System.Collection.ObjectModel.Collection<T>; but initiating the sorting in a crazy way ... passing in a parameter list of object property names in the order in which to sort them.

My initial sorting method had a switch on the property on the singular object which I wanted to get rid of due to you would have to add a new switch statement for each property you wanted to sort on ... no ideal.

private void Sort(string propertyName)
    {
        // convert to List
        List<MyClass> myCurrentClass = Items as List<MyClass>;
        // sort
        if (myCurrentClass != null)
        {
            switch (propertyName)
            {
                case "Name":
                    myCurrentClass.Sort(delegate(MyClass myClassOne, MyClass myClassTwo)
                                 {
                                     return
                                         Comparer<string>.Default.Compare(myClassOne.Name,
                                                                          myClassTwo.Name);
                                 }
                        );
                    break;
                case "Increment":
                    myCurrentClass.Sort(delegate(MyClass myClassOne, MyClass myClassTwo)
                                 {
                                     return
                                        Comparer<int>.Default.Compare(myClassOne.Increment,
                                                                     myClassTwo.Increment);
                                 });
                    break;
            }
        }
    }


After hunting around for a solution and being guided toward reflection but without any luck I decided to take the plunge and post my first ever question on StackOverflow. The community which has grown around the site has some very clever people in it so I thought I'd get at least a couple of replies ... and I had a guess that Jon Skeet would be first (as it's all he seems to do!) and I was right, woo! Anyway, I digress.



Jon suggested that I look into using Type.GetProperty and suggested that the whole concept might get a little icky. By this point I had gone past the point of wanting to put it into the original bit of code I was looking (as it would over complicate matters), but wanted to know how I could get to where I originally wanted to be. I was just about to dive back into the madness of reflection when another StackOverlow member, Frederik Gheysels posted a none generic starting point for me to head towards.



Frederik's idea almost compiled and after having a little re-jig managed to get it compiling and working how I expected it to ...



        private void Sort_version1(string propertyName)
        {
            // convert to List
            List<MyClass> myCurrentClass = Items as List<MyClass>;
            // sort
            if (myCurrentClass != null)
            {
                myCurrentClass.Sort(delegate(MyClass one, MyClass two)
                                        {
                                            PropertyInfo pi = typeof (MyClass).GetProperty(propertyName);
                                            return Comparer.Default.Compare(pi.GetValue(one, null), pi.GetValue(two, null));
                                        });
            }
        }


After looking at this, thinking before I was using the generic comparer and after the comment from Jon about the Generic one I decided that I would try and get to use the generic one and get the switch working from the type of the property ... if I could. So after putting in a break point into different places and inspecting the information I got back from PropertyInfo I decided that I would add a static method on MyClass to which would return true if the property existed, but also then return out to me the property class full name and the property info details (this could definitely be better!)



        public static bool HasDetailAndExtract(string propertyName, out string propertyType, out PropertyInfo propertyInfo)
        {
            PropertyInfo pi = typeof (MyClass).GetProperty(propertyName);
            propertyType = (pi != null) ? pi.PropertyType.FullName : string.Empty;
            propertyInfo = pi;
            return (pi != null);
        }


With this I could be a little defensive with the checking in the Sort method, but also perform the switch on the system type while still using the generic comparers which is what my original aim was.



        private void Sort_version2(string propertyName)
        {
            // convert to list
            List<MyClass> myCurrentClass = Items as List<MyClass>;
            string typeOfProperty;
            PropertyInfo pi;
            // sort
            if ((myCurrentClass != null) && (MyClass.HasDetailAndExtract(propertyName, out typeOfProperty, out pi)))
            {
                switch(typeOfProperty)
                {
                    case "System.String":
                        myCurrentClass.Sort(delegate(MyClass one, MyClass two)
                                                {
                                                    return
                                                        Comparer<string>.Default.Compare(pi.GetValue(one, null).ToString(),
                                                                                         pi.GetValue(two, null).ToString());
                                                });
                        break;
                    case "System.Int32":
                        myCurrentClass.Sort(delegate (MyClass one, MyClass two)
                                                {
                                                    return
                                                        Comparer<int>.Default.Compare(
                                                            Convert.ToInt32(pi.GetValue(one, null)),
                                                            Convert.ToInt32(pi.GetValue(two, null)));
                                                });
                        break;
                    default:
                        throw new NotImplementedException("Type of property not implemented yet");
                }
            }
        }


This all works as expected and overall I'm pretty happy with the implementation. I won't be putting it into the code I was originally writing at work purely due to the fact that this is getting more generic and would be overkill as the implementation I was doing at work was pretty specific but I'm glad I managed to get the result that I set out to get in the first place.



I guess the next challenge, when I've got time, will be to try again in vs2008 / c#3 and see how much more elegant I can get the code looking with the use of lambas and the other fun stuff in .net3.5.



As usual, any thoughts or questions then please comment and I'll reply as soon as possible!

Friday, 2 January 2009

IEnumerable Extension Methods

After looking over some questions on StackOverflow it got me thinking about extension methods. It's not really something which I have looked into much as I only use Visual Studio 2008 at home for personal projects. I stumbled upon one post about potential extension methods to add to a colaboration on CodePlex for everyones use. I was scrolling through some of the potentials to be submitted and came across this post. It intrigued me as the main method was converting an IEnumerable to a string with a separator ... so would convert an array of ints 1,2,3 into the string "1, 2, 3" if the separator was ", " ... I think you get the point.

However the way they were doing it was the usual "go through all the items, add the separator after everyone, then at the end take the last off". Personally when I see this I get a little sad. It's just not very elegant but also it means you don't harness the power of the framework ... which is what it is there for!

Side Note With the advent of .net 2.0 Generics was brought in. This opened up a whole world of fun for developers and a lot of useful things especially around the area of collections. If you've not looked at Generics I would highly recommend working your Google-Fu and doing some reading.

Anyway ... using generics I decided to refactor the ToString method for IEnumerable to use ToArray() of a List and string.join(). This might be a new way for some people of concatenating values together with a supplied separator. It leverages the power of the .net framework to do the work and avoids having to add an extra separator and then removing it once you have iterated through all the items in the list and performing the specified delegate function.

        public static string ToString<T>(this IEnumerable<T> collection,
Func<T, string> stringElement, string separator)
        {
            List<string> result = new List<string>();
            foreach (T item in collection)
            {
                result.Add(stringElement(item));
            }
            return string.Join(separator, result.ToArray());
        }


So moving on from this I thought that a List has a ForEach extension method which executes a delegate on each of the elements in the list; but not on an IEnumerable. This has been discussed and documented in so many places I'm not going to write about it here.  So what I wanted to do was break out the ForEach functionality out of the ToString implementation so it can be used injunction with it, but also by itself.


        public static IEnumerable<T> ExecuteForEach<T>(this IEnumerable<T> collection,
Func<T, T> function)
        {
            List<T> result = new List<T>();
            foreach (T item in collection)
            {
                result.Add(function(item));
            }
            return result.AsEnumerable();
        }


I made it return an IEnumerable<T> so it could be piped together to keep with the design of linq and lambda expressions etc. The limitation of this implementation is that it returns the same type as the type passed into the Func so you can't change the type, such as converting int to string. So take two came along ...


        public static IEnumerable<U> ExecuteForEach<T, U>(this IEnumerable<T> collection,
Func<T, U> function)
        {
            List<U> result = new List<U>();
            foreach (T item in collection)
            {
                result.Add(function(item));
            }
            return result.AsEnumerable();
        }


Same as the previous example, but with two different generic types, this enables the conversion of int to string, but also performing actions on the same types and returning the updated values eg. increment a list of ints.

With using the updated ExecuteForEach<T, U> (I decided on calling it ExecuteForEach as it will update / perform a function on each of the items in the collection and update them, not just perform an function on them) we can now update the ToString method call to be just two lines;  it abstracts the looping away into a different function which can be used again for different actions, but also uses the power of the framework with the string.join functionality.


        public static string ToString<T>(this IEnumerable<T> collection,
Func<T, string> stringElement, string separator)
        {
            List<string> possible = collection
.ExecuteForEach(t => stringElement(t))
.ToList();
            
            return string.Join(separator, possible.ToArray());
        }


A simple usage of this is ...


        public static string ToString<T>(this IEnumerable<T> collection, string separator)
        {
            return ToString(collection, t => t.ToString(), separator);
        }


... and the unit test to go with it ...


        [TestMethod]
        public void ToStringTest()
        {
            var ints = new int[] { 1, 2, 3 };
            var result = ints.ToString(", ");
            Assert.AreEqual("1, 2, 3", result);
        }


Hope this all makes sense, please let me know if you have any comments or thoughts about this :-)

Thursday, 4 December 2008

Visual Studio Solution Structure

I've been playing about with Visual Studio 2008 and the new features of c#3 on and off for a couple of weeks and lining up to get a couple of small projects up and running. One of them is my own website, one is a survey for next season for TDs and participants in national tour events.

I wanted to get the solution construction right for my website solution so that I can add a lot of stuff in over time and not have to re-work it to fit more things in. After setting up a subversion source control server for personal usage I decided that this was the time to mess about and I can always roll back bits if something goes wrong.

I wanted to keep the structure so that it was separated and also unit testable (yes I'm a unit test geek). This lead to having separate projects in the solution into different areas ... Data access, Model classes, Services and UI (using Solution folders works wonders for this ... more later).

*Top tip* To get your namespaces as you'd like them start by naming the projects as you'd like the namespaces to be. A good starting point is . as all the files in the projects will start with that namespace as standard unless you change them.

The data access project is self explanatory. I've decided to start using/playing with the Microsoft Entity Framework for this. I'm still learning how the EF works and best practices and I'm sure I'm still not using this properly but ah well; we live and learn! I've been reading about the Linq2Sql vs EF madness which has been going on over the past month since PDC, but I don't think it'll affect a little single "out of hours" home coder.

The model project is where all the domain model classes go. I'm still trying to work out how this goes with the EF in the data project so if any one can point out how these should operate together *properly* then some pointers would be much appreciated.

The service project is there for a wcf service project. I've put this in place so that I can access the data asynchronously via javascript in the future for an ajax look and feel with responsive UI and to avoid unnecessary postbacks.

UI is made up of a couple project types. The main one is a MS MVC project template which will serve as the main "website" in a traditional sense. It is made up of pages or views which will display different images / inputs / data and will also serve as host pages for the second UI project type; a silverlight 2 project. I've added this in as I want to start playing about with silverlight, and the eventual plan is to do my own site in both postback/views way, responsive UI javascript/async calls way and to have a RIA with silverlight.

To enable the solution to be grouped into logical I have used Solution folders to group the project and associated test project together. Solution folders are not related to the file structure they are purely there for organisational purposes. They also have more functions which can be found my reading the above link.

In addition to the grouped projects I have also added in a separate class projects for extension methods and global definitions. These projects will be referenced by one or more projects and will not reference any other project (as circular references are bad!).

Another tip I would use if you are going to go down the Unit test route would be add a file structure folder in a logical place in the solution and add in your mocking / helper dlls in this folder. You can then add in single references into each unit test project to one set of dlls. If you are putting your code into a source control system then add them into your solution and file them away into a "External" solution folder so that you can hide them away but still have them "under control".

Well this is the structure I am going to work with for a while and see how it gets on. You have any thoughts on the matter or pointers to improve this structure then please let me know.

This is the first post I've done of a technical nature so any comments about that would also be appreciated :-)