No Free Time

Because my therapist says I need to let things out

Posts Tagged ‘.net

The Visitor Pattern, Double Dispatch and Reflection Performance

leave a comment »

Was listening to Herding Code #70 this morning and heard the Visitor Pattern mentioned. It was new to me (in theory but not in practise) so I was led merrily down the garden path.

Background and definition of the Visitor Pattern.

An example of the visitor pattern in C# using double-dispatch and reflection.

A great article about reflection and MemberInfo cache.

Written by Andrew Myhre

January 29, 2010 at 12:23 am

Posted in patterns

Tagged with ,

Create a list in a SharePoint site programmatically

with one comment

Creating a list programmatically might be handy when you need to do this in a web part or, if you’re in the situation I was in today, you need to create a list where the template is not available on the Create page.

In my case I had a Collaboration site but I needed to create a Discussion Board – impossible using the SharePoint UI. How to get around this?

The first solution that occurred to me, and what I assumed I HAD to do, was to create a custom site definition. I had no idea how to go about doing this so this was a daunting prospect. But it occurred to me that, ultimately, I’ll only need to do this one time, maybe twice, and my users will never do this. So why go to all that trouble when the purpose of a site definition is to create a repeatable story for your end users? All I needed was a one shot hack.

So I remembered the SharePoint object model, and wrote an app. This app takes three arguments – Site URL, List Name, List Template ID. I used it to create a new discussion board in my site, it’s repeatable enough for my purposes, and it took me 5 minutes to write.

The code is provided below, but I want to hit home the point of this post – SharePoint is not as difficult as you think. There is always a simple way to do what you want to do. The difficulty is remembering to think outside the UI. I used to think that where SharePoint build was concerned I’d have to get used to telling customers ‘No’ but, as it turns out, that’s not that case at all.

CreateList.exe Source

1 using System;

2 using System.Collections.Generic;

3 using System.Linq;

4 using System.Text;

5 using Microsoft.SharePoint;

6

7 namespace CreateList

8 {

9 class Program

10 {

11 static void Main(string[] args)

12 {

13 if (args.Length == 0)

14 {

15 PrintListTemplates();

16 return;

17 }

18

19 bool validArgs = true;

20 if (!Uri.IsWellFormedUriString(args[0], UriKind.Absolute))

21 {

22 Console.WriteLine(“Arg 0 must be an absolute Sharepoint site URL e.g: http://mysite.com”);

23 validArgs = false;

24 }

25

26 int templateId=0;

27 if (!int.TryParse(args[2], out templateId))

28 {

29 Console.WriteLine(“Arg 2 must be a valid list template id from the following list:”);

30 validArgs = false;

31 PrintListTemplates();

32 }

33 if (!validArgs)

34 {

35 Console.WriteLine(“Invoke with no arguments to get a list of available SharePoint List templates”);

36 return;

37 }

38

39

40 Uri siteUrl = new Uri(args[0]);

41 string listName = args[1];

42

43 AddListToSite(siteUrl, listName, templateId);

44 }

45

46 private static void AddListToSite(Uri siteUrl, string listName, int SPListTemplateTypeId)

47 {

48 using (SPSite site = new SPSite(string.Format(“{0}”, siteUrl)))

49 {

50 SPWeb web = site.OpenWeb();

51 Guid listGuid = web.Lists.Add(listName, “”, (SPListTemplateType)SPListTemplateTypeId);

52 SPList list = web.Lists.GetList(listGuid, true);

53 }

54 }

55

56 private static void PrintListTemplates()

57 {

58 string[] typeNames = System.Enum.GetNames(typeof(SPListTemplateType));

59 Array typeValues = System.Enum.GetValues(typeof(SPListTemplateType));

60

61 int j = 0;

62

63 foreach (int i in typeValues)

64 {

65 Console.WriteLine(typeNames[j++].ToString() + ” “ + i.ToString());

66 }

67 }

68 }

69 }

Written by Andrew Myhre

March 21, 2009 at 12:07 am

Posted in .net, sharepoint

Tagged with , ,

Digital Wall – redux

leave a comment »

I posted last week about the release of Digital Wall to the internet – the application that lets you graffiti on our office wall from your browser. Well I was so pleased with how it performed that I scrapped the entire codebase and started again from scratch. Mostly I did it because the original version was the first time I had played with Silverlight, WPF and WCF, so I realised there was a lot that I would do differently a second time around which would make adding cool features easier. So I did it, and I added some cool features.

The new version is up at http://wall.tequila-uk.com. A number of things are different:

 

  • I can now write a welcome message on the server which will appear in your browser. I can write the welcome message in XAML. I do that using Mike Snow’s excellent tip for loading XAML into a control at runtime.
  • As well as drawing on the wall, you can now add images to it. You have two options for doing this – upload an image from your hard-drive, or provide a link to an image on the internet. Then you get to drag the image around and scale it as you desire. When you’re happy with it just click the Send button or switch to the Brush mode to have the image sent to the server.
  • The webcam is still pretty poor, so the Silverlight client will now download the server’s representation of the wall as objects and display it in your browser, overlayed on top of the stream. You can adjust the transparency of the overlay by clicking the button at the bottom of the toolbar. There are three settings: off, transparent and opaque. This way you can draw moustaches and fake wangs on people much more easily.
  • You can identify yourself (this is optional) and see who else is using the wall at the bottom-right corner of the screen.

 

And of course the wall is publishing canvases out through a number of different channels:

 

 

Previous posts: Digital Wall Goes Public, Digital Wall (provides a video demonstrating what it basically does)

To talk to me about the wall you can message me on Twitter.

Enjoy!

Written by Andrew Myhre

November 20, 2008 at 10:14 pm

Posted in digital wall

Tagged with , , , ,

Digital Wall

with one comment

Drawing Something Together

I’ve been working on a cool little project over the last few weeks. The original idea was inspired by the amazing laser-pointer graffiti these guys did, but I wanted to provide more of a collaborative, distributed angle. I wanted to let anyone see a live feed of a real physical wall, and be able to draw on that wall in their browser and have their doodling reflected in the real world.

So I came up with this:

Digital Wall Architecture Diagram - not to scale

Digital Wall Architecture Diagram - not to scale

I’ll touch on each of the architecture points in turn.

Application Layer

At core the wall relies on a WPF application which is reponsible for actually drawing the current digital wall image on the physical wall using a projector. I used an InkCanvas control to display any drawing data that is ‘current’ (meaning it hasn’t been wiped off the wall yet). The drawing data for the control can be created remotely in Silverlight or directly at the machine using a Wii remote, using Brian Peek’s Managed Library for Nintendo’s Wiimote.

The drawing data is stored in a SQL database, which has a single table Drawings. Each row in that table is a single ‘stroke’, in the sense of what you draw between pressing the left mouse button down and lifting it up again on the canvas. Any drawings stored in the table are swept up by the WPF application, added to the InkCanvas’ strokes collection, and then the whole canvas is captured to an image. That image is then applied to the application background and the InkCanvas’ strokes collection is cleared out. Using this technique I was able to get some performance improvements out of the application because keeping loads of Stroke objects in memory was way to intensive.

The application is also encoding a webcam stream of the physical wall, so that anyone connecting in their browser can see actual footage of the wall. I could have just downloaded the drawing data directly to Silverlight and rendered them in the browser using the same method as the WPF application, but I wanted to give remote users a real sense that they’re changing a physical environment. We’re using Windows Media Encoder to encode the stream and a service called Stream Web Town to make the stream available for broadcast. SWT provide a free streaming service which is limited in a couple of ways but dead useful to get a simple proof of concept up and running.

Finally the app is screen capturing the current wall every minute or so and saving out to a predefined network location, so we can see a complete history of what gets drawn. This is essential because currently the wall erases itself every 10 minutes, so it’s the only way people would be able to see what they’ve drawn.

The Browser

The Silverlight application is doing three things. First, the webcam feed is being streamed to the background of the canvas, so a user can see exactly what’s already on the wall. Second, another InkCanvas control allows the user to draw directly on the canvas. Third, when you’re ready the Silverlight app will send the drawing data to the database for the WPF app to pick up.

The communication layer was written in WCF and basically consists of a single method AddGeometry(), which requires some simple data like IP, colour and the actual data, which is just a list of points serialised to comma delimited values. The website that the Silverlight application available at is also hosting the WCF service. It also provides an RSS feed of all the screen grabs saved from the WPF app.

Cool so that’s a brief explanation of what I’ve built, I’ll try to get some more information up at some point, and more pictures and video too.

Written by Andrew Myhre

November 6, 2008 at 5:54 am

Posted in digital wall

Tagged with , , , ,

Load ASP.Net MVC Routes dynamically at runtime from a repository

with 10 comments

This article was written for a preview version of ASP.Net MVC and is now out of date.

Source for this example

Today I read Ian Suttle’s post about loading MVC routes dynamically from a SQL database. I think it’s a cool idea, and I wanted to see if I could do the same thing with XML or a configuration file. I also wanted to introduce the factory design pattern so that people can plug in their own route repositories.

My solution comprises the following classes:

  • MvcRoute – main route DTO
  • MvcRouteParam – route parameter DTO
  • IRouteService – interface defining a service which loads route data from a repository
  • RouteServiceBase – abstract class handles most common route service operations
  • ConfigRouteService – extends RouteServiceBase,  is responsible for reading configuration settings and constructing an IRouteService
  • DynamicRoutesConfigurationHandler and DynamicRoutesConfiguration – parse the configuration

A couple of caveats:

  • It’s not complete, it’s a proof of concept
  • It doesn’t handle ‘ignore’ routes

Settings your routes looks like this:

  

  

24 protected void Application_Start()

25 {

26 IRouteService routeService = new ConfigRouteService();

27 routeService.SetAppRoutes(RouteTable.Routes);

28 RegisterRoutes(RouteTable.Routes);

29 }

 

IRouteService is implemented thusly:

 

  

11 namespace DynamicRoutes

12 {

13 public interface IRouteService

14 {

15 List<MvcRoute> GetConfiguredRoutes();

16 RouteCollection ResetAppRoutes(RouteCollection RouteTable);

17 RouteCollection SetAppRoutes(RouteCollection RouteTable);

18 RouteCollection SetAppRoutes(RouteCollection RouteTable,

19 List<MvcRoute> ConfiguredRoutes);

20 }

21 }

 

 

Most importantly you have a method to get route data from your chosen repository (GetConfiguredRoutes) and a method to add the routes to your application RouteTable (SetAppRoutes).

 

The RouteServiceBase class implements all methods except GetConfiguredRoutes, and this should be the only method you need to implement yourself in order to set up a new route repository. For example, here’s the implementation for ConfigRouteService:

 

 

9 namespace DynamicRoutes

10 {

11 public class ConfigRouteService : RouteServiceBase

12 {

13 public override List<MvcRoute> GetConfiguredRoutes()

14 {

15 DynamicRoutesConfigurationSection configuration =

16 ConfigurationManager.GetSection(“dynamicRoutes”) as

17 DynamicRoutesConfigurationSection;

18

19 return configuration.Routes;

20 }

21 }

22 }

 

 

And here are the configuration handler classes:

 

 

7 namespace DynamicRoutes

8 {

9 public class DynamicRoutesConfigurationHandler : IConfigurationSectionHandler

10 {

11 public object Create(object parent, object configContext, System.Xml.XmlNode section)

12 {

13 DynamicRoutesConfigurationSection config = new DynamicRoutesConfigurationSection();

14 config.LoadRoutesFromConfig(section);

15 return config;

16 }

17 }

18 }

  

8 namespace DynamicRoutes

9 {

10 public class DynamicRoutesConfigurationSection : ConfigurationSection

11 {

12 public List<MvcRoute> Routes { get; set; }

13 public string TypeName { get; set; }

14 public void LoadRoutesFromConfig(XmlNode section)

15 {

16 Routes = new List<MvcRoute>();

17 TypeName = section.Attributes[“type”].Value;

18 foreach (XmlNode node in section.ChildNodes)

19 {

20 if (node.Name == “route” && node.Attributes[“type”].Value == “map”)

21 Routes.Add(new DynamicRouteConfiguration().LoadRouteMappingFromConfig(node));

22 }

23 }

24 }

25

26 public class DynamicRouteConfiguration

27 {

28 internal MvcRoute LoadRouteMappingFromConfig(XmlNode routeNode)

29 {

30 MvcRoute route = new MvcRoute();

31

32 route.routeName = routeNode.Attributes[“name”].Value;

33 route.routePattern = routeNode.Attributes[“pattern”].Value;

34 route.routeParams = new List<MvcRouteParam>();

35

36 foreach (XmlNode node in routeNode.ChildNodes)

37 {

38 if (node.Name == “param”)

39 route.routeParams.Add(LoadParamFromConfig(node));

40 }

41

42 return route;

43 }

44

45 internal MvcRouteParam LoadParamFromConfig(XmlNode paramNode)

46 {

47 MvcRouteParam param = new MvcRouteParam();

48

49 param.paramKey = paramNode.Attributes[“key”].Value;

50 param.paramValue = paramNode.Attributes[“defaultValue”].Value;

51

52 return param;

53 }

54 }

55 }

 

 

Finally, here’s what’s in my web.config to set up my default route:

 

 

11 <configSections>

12 <section name=dynamicRoutes type=DynamicRoutes.DynamicRoutesConfigurationHandler, DynamicRoutes/>

13 </configSections>

14

15 <dynamicRoutes>

16 <route type=ignore url={resource}.axd/{*pathInfo}/>

17 <route type=map name=Default pattern={controller}/{action}/{id}>

18 <param key=controller defaultValue=Home/>

19 <param key=action defaultValue=Index/>

20 </route>

21 </dynamicRoutes>

 

 

This all probably sounds like nonsense so download the complete source here.

Written by Andrew Myhre

August 2, 2008 at 2:08 am

Posted in .net

Tagged with ,

Howto: Only include part of a project workspace in a TFS 2008 Team Build

with 2 comments

I’m working on a website with a large design aspect, so we have a lot of .psd files (about 200mb) kicking about the place. We want them source controlled, so they live in the TFS 2008 team project folder in source control. But then our Team Build includes them when downloading the source files, so that quickly fills up our build server’s drive and makes a single build take up to 11 minutes, which is far too long for a basic eCommerce website.

So I trimmed these files from our build process. Here’s what I did:

  1. Copy the .psd files and any other files that aren’t required for a build into a seperate folder in the root of the team project. (All our website/source files are in another folder called ‘Current’, as in the ‘current version’, as opposed to ‘Phase 1’, ‘Phase 2’)
  2. In Team Explorer, right click the build you want to edit and selected Edit Build Definition…
  3. In the Workspace tab, enter the path within source control where you want to start downloading files from. In our case I chose the $/[project]/Current folder, so the /PSDs folder will be ignored and not downloaded.

Now, thanks to the above steps my build history folders are 1/10th the size they were to begin with, and the build process takes less than half the time!

Written by Andrew Myhre

July 17, 2008 at 12:56 am

Posted in infrastructure

Tagged with , ,

Enabling WCF in IIS 7 on Vista

with one comment

I created a Silverlight-enabled WCF service which worked perfectly when running my Silverlight app from Visual Studio, but as soon as I deployed to IIS 7 on my machine and opened it outside of VS I received the following error:

Unhandled Error in Silverlight 2 Application Exception has been thrown by the target of an invocation. at System.RuntimeMethodHandle._InvokeMethodFast
…… (there was more

I couldn’t be sure whether this was a Silverlight or a WCF issue so I opened the SVC url in my browser and received a (405) Method Not Allowed response. I checked IIS and discovered there was no HTTP Handler set up for WCF services.

I then managed to find this very helpful post about setting up WCF HTTP Handlers in IIS 7, and the solution described worked perfectly for me. Here are the steps:

  1. Open a command prompt as administrator
  2. CD to c:\Windows\Microsoft.NET\Framework\v3.0\Windows Communication Foundation
  3. Type ServiceModelReg -i and press return
  4. A whole load of lines like “Installing: HTTP Handlers” will print out to the console. When it’s finished go into IIS 7 and open the HTTP Handlers list for your website. You should see a couple of new ones for the *.svc extension

Also, another issue I came across while trying to track down how to set these up was where people were deploying their WCF/Silverlight project to IIS 7 without updating their web.config to change the server binding reference. When you add a service reference to your Silverlight project the url is stored in the ServiceReferences.ClientConfig file, but if the WCF project is defined in the same solution then the URL will point to the local Cassini server, which means the service call will fail when you deploy the app to IIS.

One solution to the issue is to override the service URL in code, so that you don’t have to keep updating the .config file when you deploy to a web server.

Written by Andrew Myhre

July 13, 2008 at 3:54 am

Posted in infrastructure

Tagged with , , ,

How to create a default instance of a type T

leave a comment »

A problem I’ve come across in the past when writing ORM solutions is when I need to create a new instance of generic type T but set to a NULL or 0 value. Value types I need to set to null but reference types I need to set to 0. How do I do the right thing? Here’s a bad way:

if (typeof(container) == typeof(int))
container = 0;
else if (typeof(container) == typeof(Customer))
container = null;

Using this method means lots of if … else if …else by checking type. How ugly! There has to be a better way, I thought. So I gave up and got on with something else.

Months later, it turns out there IS a better way: the default keyword:

t container = default(containerType);

This keyword gives you a NULL or 0 value based on the type you pass it. I don’t know whether it’s faster or more efficient, but hey, it’s a lot less code for you to write, and you can be pretty sure they’ve covered all the edge cases.

More information about the default keyword.

Written by Andrew Myhre

July 11, 2008 at 4:41 am

Posted in .net

Tagged with ,

ASP.Net MVC: Giving MasterPages access to ViewData

with 3 comments

If you want to include ViewData in the MasterPage UI, you can.

ASP.Net MVC MasterPages are System.Web.Mvc.ViewMasterPage – this is a generic type just like System.Web.Mvc.ViewPage. So you can type it with a ViewData object, like this:

public partial class MyTemplate : ViewMasterPage<SomeViewData>

As soon as you do this you’re saying that the SomeViewData class is the only ViewData object that can be used on any page using this template. Not a problem though, just create a base ViewData class.

public class SiteWideViewData
{
}

public class PageViewData : SiteWideViewData
{
}

This of course means no more default ViewData objects and no more return View(); I found the easiest way to deal with that is to create a static property on the base ViewData:

public class SiteWideViewData
{
public static SiteWideViewData Default { get { return new SiteWideViewData(); } }
}

Now I can do this:

public ActionResult MySimpleControllerMethod()
{
return View(SiteWideViewData.Default);
}

And that seems to work okay.

Written by Andrew Myhre

July 3, 2008 at 6:38 pm

Posted in .net

Tagged with ,

Where to manage the build location in TFS 2008

with one comment

Until now I’d been confused between the agent working directory, the build service accounts’s temp folder, and the workspace created by Team Build. Do I have to manage all three settings? Do they have to be different? Today I discovered there’s just one location I need to manage for each build agent.

In my efforts to clean up and standardise where projects are being downloaded and built on our build server I discovered that the workspaces automatically created by Team Build don’t actually determine where the build happens. This is because every time TFS performs a build it deletes and recreates a workspace for that build. The source directory path it uses comes from the Build Agent definition:

Build Agent Working Directory

Written by Andrew Myhre

May 13, 2008 at 11:11 pm

Posted in infrastructure

Tagged with , ,