Welcome to MSDN Blogs Sign in | Join | Help

Entity Framework 4: POCO and Foreign Keys in Beta 2 – updates not persisted

Whilst preparing some demos for a customer session on Entity Framework 4 recently, I was putting together a demo to show how Entity Framework can work with POCO types. The intention was to show code that worked with the automatically generated types and then switch out the types for a POCO implementation and show that the same code still ran, complete with change tracking and lazy loading.

Unfortunately, as I put the code together I was unable to get it working so I had to modify the demo. I’ve since discovered that I had encountered a known issue in Beta 2 that has been fixed in later builds!

I had code along the lines of the following:

using (var context = new NorthwindEntities())
{
    var customer = context.Customers.Single(c => c.CustomerID == "AROUT");
    var product = context.Products.Single(p => p.ProductID == 1);
    var order = new Order()
    {
        OrderDate = DateTime.Today,
        Customer = customer,
    };

    Order_Detail orderDetail = new Order_Detail
    {
        Product = product,
        Quantity = 1,
    };
    order.Order_Details.Add(
        orderDetail
        );

    context.Orders.AddObject(order);
    context.SaveChanges();
}

With this code, the newly created order wasn’t being saved to the database. It turns out that there are a couple of workarounds:

  • use customer.Orders.Add(order) instead of order.Customer = customer (and similiarly for the product reference on the order details)
  • set order.Customer = customer after adding the order to the context (i.e. after the AddObject call)

I opted for the latter workaround as it seemed slightly simpler to me. Sure enough, I was up and running again in a jiffy.

using (var context = new NorthwindEntities())
{
    var customer = context.Customers.Single(c => c.CustomerID == "AROUT");
    var product = context.Products.Single(p => p.ProductID == 1);
    var order = new Order()
    {
        OrderDate = DateTime.Today,
        //Customer = customer,
    };

    Order_Detail orderDetail = new Order_Detail
    {
        //Product = product,
        Quantity = 1,
    };
    order.Order_Details.Add(
        orderDetail
        );

    context.Orders.AddObject(order);
    orderDetail.Product = product; // BUG in Beta 2 - set this after adding the order to the context
    order.Customer = customer; // BUG in Beta 2 - set this after adding the order to the context
    context.SaveChanges();
}

Looking forward to the next release!

Posted by stuartle | 0 Comments
Filed under:

Capturing pop-up windows with Web Test Recorder in Internet Explorer 8 (IE8)

** As always, use this at your own peril. This post is entirely based on my experience – your mileage may vary! **

I was working with a customer who were having trouble recording a web test using the Web Test Recorder in Visual Studio Team Suite Test Edition. As they clicked through the site that they were testing, one of the links opened a new window to display some data. The web test recorder was capturing interactions through the original window, but nothing was being captured from the newly opened window. As is normal for problems with the web test recorder, we went through the steps in Mike Taute’s troublshooting guide but still weren’t able to resolve the issue.

Based on a helpful reply from an internal discussion list, it would seem that the problem is related to the way IE8 uses processes for isolation. Fortunately, I found a post on the AskIE blog that seems promising: Opening a New Tab may launch a New Process with Internet Explorer 8.0. When we tried setting the TabProcGrowth value to 0 and restarting Internet Explorer stopped creating new processes when the new window was created and the web test recorder captured the full output. If you’re considering trying this change then I strongly recommend reading the AskIE post to find out more about the implications of making this change.

Posted by stuartle | 0 Comments
Filed under: ,

T4MVC now with multiple file support

Ok, so I’m indulging in self-publicity a little with this post, but I really want to take the opportunity to highlight some great work that David Ebbo has done. I’ve been spending a bit of time with ASP.NET MVC Framework and really like it. The combination of testability, being led towards separation of concerns, massive amounts of extensibility and the way it aligns to HTTP all resonate quite strongly for me. I’m not saying for a minute that Web Forms is dead, but I do believe it is getting some serious competition from the MVC Framework!

However, there has always been one area of the MVC Framework that just hasn’t sat well with me: magic strings. I.e. things for which the compiler doesn’t provide verification, refactoring won’t necessarily recognise, and intellisense provides no support! I’ve given a couple of examples below:

return View("ResetSuccess"); // render a non-default for this action
<%= Html.ActionLink("Details", "ShowCustomer", new { customerID="ABCDE" } )%>

In the examples above, “ResetSuccess” and “ShowCustomer” are used to refer to a view and an action respectively and are clearly magic strings. The “customerID” property on the anonymous type we’re creating is also essentially a magic string: the compiler can’t check that it actually matches a parameter on the action we are invoking. Fortunately there are ways around this. One way is to use the strongly typed helpers from the MvcFutures project. These let you use syntax along the lines of

<%= Html.ActionLink<CustomerController>(c => c.ShowCustomer("ABCDE") )%>

This does now give you compiler checking etc, but I’m not entirely sure about the syntax and there have been some questions raised around the performance (although I have to admit that I haven’t had chance to verify that).

Another option (and the one that I’ve been using recently) is David’s T4MVC. You can download it from here and read more about it on David’s blog here, but to revisit the previous examples using T4MVC:

return View(MVC.Home.ResetSuccess); // render a non-default for this action
<%= Html.ActionLink("Details", MVC.Customer.ShowCustomer("ABCDE") )%>

I find this a really nice way to navigate through my controllers and views. It’s probably worth pointing out that it also works for referencing partial views, setting up routes, … essentially any place I’ve needed to refer to items in code it has helped me so far. I won’t spend a huge amount of time going through how this all works but I would encourage you to take a look at the code that gets generated. David has done some really neat stuff to ensure that it all works with intellisense/refactoring by deriving a new class from existing controllers and using a custom ActionResult to capture the action parameters etc. The latest update has some minor changes by yours truly (although most of the work was already done thanks to Damien Guard’s Multiple File Manager!) to allow you to generate separate files for each controller to make it easier to work with T4MVC in a team with multiple developers checking code out.

Personally, I’m a huge fan of T4MVC and find that it provides a simple, discoverable way to reference views, actions etc. So, what are you waiting for? Go and download it now!

 

UPDATE: T4MVC now has its own homepage on codeplex: http://aspnet.codeplex.com/wikipage?title=T4MVC

Posted by stuartle | 0 Comments

Options for creating a test project

I was rooting through the Tools\Options dialog in Visual Studio recently and noticed the following options for Test projects:

image

Whilst these are probably reasonable defaults in terms of discoverability of features, I’ve always found that the first thing I did when creating a test project was to delete the introduction file and manual test (and sometimes the unit test, depending on what I’m doing). I’ve now unticked all of the options, so I get an empty project and just add what I need.

It’s a small thing, but I like it!

Posted by stuartle | 0 Comments
Filed under:

Setting the window title for a command prompt

Very quick tip in what seems to have become a mini-series (Part 1, Part 2). I often find myself with a number of command windows open and switching between them can be problematic. To address this I use the “title” command to set the window title, and have found that setting the title to match the current directory works well. To achieve this quickly you can use the following command

@title %CD%

And, of course, you can wrap this in a batch file and put it in your path to make it easier to remember and use.

Posted by stuartle | 0 Comments
Filed under: ,

Finding files in your path environment

Occasionally I’m working at the command prompt and have a utility that is in the path environment, but need to find where the file actually is. So, I wrote a little batch file that does exactly that

@echo off
echo Searching path for %1
if "%~$PATH:1"=="" goto :notfound
echo Found: %~$PATH:1
goto :end

:notfound
echo Unable to find %1
goto :end

:end

The batch file takes a single argument which is the filename to find. The magic happens in the "%~$PATH:1" part – this basically searches the directories in the PATH environment variable for first argument passed to the batch file. All of the rest of the batch file is geared towards producing nice output!

NOTE – use this at your own risk. If it deletes all of your files or replaces the text of your important documents with Lorem Ipsum then you didn’t get it from me!

NOTE 2 – if you want to find out about the other expansion options for environment variables then type “HELP FOR” at the command prompt.

** UPDATE 2009/08/20 **:

It turns out that there’s a better way to do this: the WHERE command – thanks Rupert!

The WHERE command will list all locations that it found a match in the path, also allows wildcards and is generally more flexible. Time to delete that batch file...

I’m not sure when this command appeared. It is listed in the command-line reference for Windows Vista, but not for Windows XP.

Posted by stuartle | 0 Comments

PowerShell script to clean and zip a directory

As part of my role I’m often sending sample code to customers. Sometimes this is a small snippet inline in an email, but often it will be a zipped up Visual Studio solution. Simply zipping up the folder as-is ends up including bin and obj directories which bloat the zip. Performing a clean in Visual Studio helps, but I ended up writing a PowerShell script to perform the directory clean. It turned out to be reasonably simply to put together:

Get-ChildItem . -recurse -force -include bin,obj,*.tmp,*.user,*.sqlsuo,*.vssscc,*.vspscc,_UpgradeReport_Files | foreach -process {Remove-Item $_.FullName -Force -Recurse}

The command performs a recursive clean starting from the current directory and removes files and directories that I’m generally not interested in including in the zip file. So far this has made a massive difference to the size of zip files that I’ve sent. Although this has proved to be a useful script, I recently spent some time updating it to perform the directory zipping. This turned out to be a little trickier and I ended up pulling snippets together from a number of sources on the internet.

$Directory = Get-Item .
$ParentDirectory = Get-Item ..
$ZipFileName = $ParentDirectory.FullName + "\" + $Directory.Name + ".zip"

if (test-path $ZipFileName) {
  echo "Zip file already exists at $ZipFileName"
  return
}

set-content $ZipFileName ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
(dir $ZipFileName).IsReadOnly = $false

$ZipFile = (new-object -com shell.application).NameSpace($ZipFileName)

$ZipFile.CopyHere($Directory.FullName)

The first few lines of this snippet set up a couple of variables to make life easier later. Then it tests if the zip already exists and bails out if so. Then we get on to the interesting task of creating the zip file using a combination of directly to the file and calling the Shell.Application object.

You can either save these as separate scripts, or combine them into a single script. Note that I’m still trying to convert to PowerShell after far too long writing batch files so I make no claims that this is the best way to write a PowerShell script. In fact I make no claims about this, so use with caution in case it deletes the document you spent all night finishing or wipes your hard drive.

Posted by stuartle | 0 Comments
Filed under: ,

Quickly creating an Outlook rule

I’ve had a couple of conversations with people recently where they’ve said that they keep meaning to set up an Outlook rule to move specific messages to a separate folder. On each occasion the need to navigate the Tools\Rules And Alerts window seems to have been enough to put the task off. Unfortunately, they weren’t aware that you can right click on a message and choose Create Rule. This brings up a simpler dialog that contains pre-completed options based on the message you had selected (e.g. messages from this sender, with this subject, …) which is my preferred way of creating rules! Official documentation: http://office.microsoft.com/en-us/outlook/HA100968031033.aspx#4

Posted by stuartle | 0 Comments
Filed under:

Adding links containing spaces to an email message

Possibly slightly off-topic for this blog, but so far I’m doing quite a good job of not settling down on a single topic ;-)

Outlook has the nice feature that if you type something that looks like a link into an email, it will automatically create the link for you. Now, suppose you have a share on a server: “\\server\Some Share” (without the quotes). If you simply type this in, Outlook is confused by the space and you end up with

image

Fortunately there is a simply workaround. Unfortunately, very few people seem to be aware of it! All you need to do is enclose the link text in angle brackets. So you’d actually type “<\\server\Some Share>” (without the quotes). Now when Outlook creates the link, it uses the full text between the brackets:

image

And that’s it! Now start using it, and tell everyone else about it. You can always point them to the official write-up if you’d rather.

Posted by stuartle | 2 Comments
Filed under:

ADPlus, Windows 7 and ASP.Net

I’ve been working through some crash dumps with ADPlus and WinDBG recently and hit a couple of snags that seem to be related to running ADPlus on Windows 7. John Robbins gives details of the first issue I hit and points out that the output from tlist.exe (which ADPlus uses) had changed. The post also notes that the issue is fixed in later releases of the Debugging Tools (version 6.11.1.402 and later), so I upgraded. With 6.11.1.404 installed, I started to get a different error:

Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation. All rights reserved.

Attaching the debugger to: W3WP.EXE_-MyAppPool-_-v_-v2.0-_-l_-webengine4.dll-_-a_-.-pipe-iisipm1417f766-136f-4838-8332-861176da3119_-h_-C-inetpub-temp-apppools-MyAppPool.config-_-w_--_-m_0_-t_20
                               (Process ID: 3412)
Error creating file: C:\Program Files\Debugging Tools for Windows (x64)\Hang_Mode__Date_07-22-2009__Time_15-32-0505\CDBScripts\PID-3412__W3WP.EXE_-MyAppPool-_-v_-v2.0-_-l_-webengine4.dll-_-a_-.-pipe-iisipm1417f766-136f-4838-8332-861176da3119_-h_-C-inetpub-temp-apppools-MyAppPool.config-_-w_--_-m_0_-t_20.cfg Error: 76 -
Path not found

On a successful run, I’d expect to see

Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation. All rights reserved.

Attaching the debugger to: W3WP.EXE_MyAppPool
                               (Process ID: 3412)

The key difference is the text after “Attaching the debugger to:”. Looking through the adplus script, the name used there is built up from the process name and the application pool name. In order to get the name of the application pool, adplus uses the command line from the tlist output.

On my machine (and also on a colleague’s Windows 7 machine) the command line for w3wp.exe is along the lines of

c:\windows\system32\inetsrv\w3wp.exe -ap "MyAppPool" -v "v2.0" -l "webengine4.dll" -a \\.\pipe\iisipm1417f766-136f-4838-8332-861176da3119 -h"C:\inetpub\temp\apppools\MyAppPool.config" -w "" -m 0 -t 20

On a Windows Server 2008 box that I had access to the command line is similar, but the big difference is that the –ap parameter (which specifies the application pool name) appears at the end of the command line. Looking back at the adplus script, it seems to assume that the –ap parameter will be at the end. I made a small change to my adplus script to only pull back the quoted value (with no regard for how to handle embedded quotes). The point to make the change is after the following code

if g_CurrentProcesses(PCount).Name = "W3WP.EXE" Then
    ' read the next line
    if not objTextFile.AtEndofStream Then
        strAux = objTextFile.ReadLine
        ' check the command line for the -ap parameter
        If InStr(strAux, "-ap") Then
            arrAux = split(strAux, "-ap", -1, 1)
            strPackageName = trim(arrAux(1))

All that is needed is to add the following code immediately after the last line above (NOTE: as always, use this entirely at your own risk!!!)

' modifications start (http://blogs.msdn.com/stuartleeks/archive/2009/07/22/adplus-windows-7-and-asp-net.aspx)
If Mid(strPackageName, 1, 1) = """" Then
    strPackagename = Mid(strPackageName, 2, InStr(2,strPackageName, """") - 2)
End If
' modifications end

With this change in place, I’m back in business with adplus! As mentioned, I got this behaviour on my Windows 7 machine using version 6.11.1.404 of the Debugging Tools for Windows. I make no claims that the change above will work for you, or even that it won’t delete all your files ;-). Hopefully this will be addressed in a future release of the Debugging Tools…

Posted by stuartle | 2 Comments
Filed under:

Improving ObjectQuery<T>.Include – Updated

Having spent some time using the sample from my previous post on ObjectQuery.Include, I’ve encountered a bug! It turns out that the code generates the wrong include string for

context.Customers.Include(c => c.Order.SubInclude(o=>o.OrderDetail))

The fix for this is a small change to the BuildString method to recurse up the MemberExpression if necessary. The updated code is below  - usual disclaimers apply!

    public static class ObjectQueryExtensions
    {
        public static ObjectQuery<TSource> Include<TSource, TPropType>(this ObjectQuery<TSource> source, Expression<Func<TSource, TPropType>> propertySelector)
        {
            string includeString = BuildString(propertySelector);
            return source.Include(includeString);
        }
        private static string BuildString(Expression propertySelector)
        {
            switch (propertySelector.NodeType)
            {
                case ExpressionType.Lambda:
                    LambdaExpression lambdaExpression = (LambdaExpression)propertySelector;
                    return BuildString(lambdaExpression.Body);

                case ExpressionType.Quote:
                    UnaryExpression unaryExpression = (UnaryExpression)propertySelector;
                    return BuildString(unaryExpression.Operand);

                case ExpressionType.MemberAccess:

                    MemberExpression memberExpression = (MemberExpression)propertySelector;
                    MemberInfo propertyInfo = memberExpression.Member;

                    if (memberExpression.Expression is ParameterExpression)
                    {
                        return propertyInfo.Name;
                    }
                    else
                    {
                        // we've got a nested property (e.g. MyType.SomeProperty.SomeNestedProperty)
                        return BuildString(memberExpression.Expression) + "." + propertyInfo.Name;
                    }

                case ExpressionType.Call:
                    MethodCallExpression methodCallExpression = (MethodCallExpression)propertySelector;
                    if (IsSubInclude(methodCallExpression.Method)) // check that it's a SubInclude call
                    {
                        // argument 0 is the expression to which the SubInclude is applied (this could be member access or another SubInclude)
                        // argument 1 is the expression to apply to get the included property
                        // Pass both to BuildString to get the full expression
                        return BuildString(methodCallExpression.Arguments[0]) + "." +
                               BuildString(methodCallExpression.Arguments[1]);
                    }
                    // else drop out and throw
                    break;
            }
            throw new InvalidOperationException("Expression must be a member expression or an SubInclude call: " + propertySelector.ToString());

        }

        private static readonly MethodInfo[] SubIncludeMethods;
        static ObjectQueryExtensions()
        {
            Type type = typeof(ObjectQueryExtensions);
            SubIncludeMethods = type.GetMethods().Where(mi => mi.Name == "SubInclude").ToArray();
        }
        private static bool IsSubInclude(MethodInfo methodInfo)
        {
            if (methodInfo.IsGenericMethod)
            {
                if (!methodInfo.IsGenericMethodDefinition)
                {
                    methodInfo = methodInfo.GetGenericMethodDefinition();
                }
            }
            return SubIncludeMethods.Contains(methodInfo);
        }

        public static TPropType SubInclude<TSource, TPropType>(this EntityCollection<TSource> source, Expression<Func<TSource, TPropType>> propertySelector)
            where TSource : class, IEntityWithRelationships
            where TPropType : class
        {
            throw new InvalidOperationException("This method is only intended for use with ObjectQueryExtensions.Include to generate expressions trees"); // no actually using this - just want the expression!
        }
        public static TPropType SubInclude<TSource, TPropType>(this TSource source, Expression<Func<TSource, TPropType>> propertySelector)
            where TSource : class, IEntityWithRelationships
            where TPropType : class
        {
            throw new InvalidOperationException("This method is only intended for use with ObjectQueryExtensions.Include to generate expressions trees"); // no actually using this - just want the expression!
        }
    }

 

UPDATE: Alex James has a great post on Eager Loading Strategies that I'd recommend reading.

 

Posted by stuartle | 1 Comments
Filed under: ,

Cheating at Scrabble with LINQ to Objects

I read an interesting post on Eric Lippert’s blog recently where he was using LINQ to Objects to find possible words from a set of letters in Scrabble (he wasn’t actually cheating – that just makes for a more interesting title!). Eric made a great follow-up post that highlights the need for both defining performance goals and for profiling when working to improve performance. I thoroughly recommend reading both Eric’s posts because they are great posts - plus they set the scene for this post ;-). In Eric’s posts, he noted that he’d met his performance goals for the code but having taken a copy of the code and started to play with it, I became the new user. I guess that I can be a little impatient at times and wanted it to feel as though the results were returned instantly! I stuck with Eric’s decision to not simply cache the dictionary in memory – after all, I may want to use a dictionary that won’t fit into memory at some point.

Running the profiler against the code on my machine shows that even before the modifications in Eric’s second post, reading the data from disk is the bottleneck on my machine. This highlights another issue with profiling your application: you need to perform the profiling on representative hardware. In my case I’m running the application on a laptop so it may be that my hard drive is slower. Having said that, the changes from Eric’s post still made a noticeable difference to performance:

Method Search time(ms)
Original 2700
Updated 1658

Having determined that reading from disk is the culprit (at least on my machine!), I looked through the code again. In the original code, the SearchDictionary method is called once with the original rack and then 26 further times as a result of adding an extra letter to the rack (to allow matching to existing tiles on the board).

First off, I refactored the code slightly and introduced a SearchResult class

class SearchResult
{
    public string Rack { get; set; }
    public IEnumerable<string> Words { get; set; }
}

This allows my Search method to return an IEnumerable<SearchResult> that includes the original rack plus the virtual racks formed by using a letter from the board. My implementation of the SearchDictionary method now handles searching with the additional letters. With this change in place I can now update the search method so that it only hits the file once. Without boring you with the details too much, I could have just added the extra items to the HashSet that Eric added in his second post but I wanted to be able to correlate the matches with the original rack for outputting the results (essentially I constrained myself to producing the same output as the original method). I created a type to correlate the original and expanded/canonicalised rack info (called RackInfo) and set up a dictionary keyed on the rack value after expansion for placeholders and canonicalisation. This dictionary can then replace the HashSet.

The original LINQ to Objects query to perform the matching was

from line in FileLines(DictionaryFilename)
where line.Length == originalRack.Length
where racks.Contains(Canonicalize(line))
select line;

Since we’re working with the original rack and the rack combined with additional letters, the line length clause needs a minor tweak. The racks.Contains also needs tweaking to use ContainsKey. Other than that, the main part of the query remains unchanged!

from line in FileLines(DictionaryFilename)
where line.Length == originalRack.Length || line.Length == originalRack.Length+1
where groupedRackInfos.ContainsKey(Canonicalize(line))
select new { Word = line, OriginalRacks = groupedRackInfos[Canonicalize(line)] };

Notice that the results of this query is an IEnumerable that returns each matched word along with the racks that produced a match for that word. The results need to be re-shaped back into the matches for each rack, but even with this small amount of extra work (done with LINQ to Objects, naturally!) the timings speak for themselves:

Method Search time(ms)
Original 2700
Updated 1658
Single file pass 108

Not a bad result. In fact, it feels near enough to instantaneous to me so I’m calling it a day on this one!

I should probably point out that this post isn’t a dig at the method that Eric used. He was the only consumer and decided (perfectly validly) that the performance was sufficient. On my machine I decided that it wasn’t (hmm, maybe I need to become more patient!). The key things about this for me are that you need to define your performance goals, measure the performance against those goals and then profile your app to determine where the performance bottlenecks are. Oh, and that LINQ to Objects is pretty powerful – I was able to make this change very easily and with minimal change to the original query.

Posted by stuartle | 4 Comments
Filed under: ,

Creating database connections with Unity – part 2

Last time we looked at how to set up the configuration file so that Unity would wire up an object that took an IDbConnection parameter in its constructor. Whilst the solution works, it is easy for the various connection strings to become buried away in the Unity configuration. Also, the application configuration file already has somewhere to put connection details: the connectionStrings Element. This seemed like the ideal place to store my connection strings so I wanted a way to hook this up using Unity. After hunting around the documentation for a while, I noticed that as well as specifying parameters as dependencies (as in the previous post) you can also specify a value. This value has to be entered as a string in the configuration file but you can use the typeConverter attribute to specify the type converter that should be used to turn the string into the appropriate type. At this point the light bulb flicked on and DbConnectionNameTypeConverter entered stage left.

NOTE: the code below isn’t production ready (and as always, is subject to the standard disclaimer: “These postings are provided "AS IS" with no warranties, and confer no rights. Use of included script samples are subject to the terms specified at http://www.microsoft.com/info/cpyright.htm”).

public class DbConnectionNameTypeConverter : TypeConverter
{
    public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
    {
        string connectionStringName = (string) value;
        ConnectionStringSettings connectionStringSettings = ConfigurationManager.ConnectionStrings[connectionStringName];

        DbProviderFactory providerFactory = DbProviderFactories.GetFactory(connectionStringSettings.ProviderName);
        IDbConnection connection = providerFactory.CreateConnection();
        connection.ConnectionString = connectionStringSettings.ConnectionString;
        return connection;
    }
}

This code simply takes the string passed in and looks up the connection details with that name. It uses the DbProviderFactory to create the connection, so it will handle SqlConnection or any other connection type that is registered. With this class in place, we can move the connection configuration to the connectionStrings section:

<connectionStrings>
    <add name="AdventureWorks"
         connectionString="Data Source=(local);Database=AdventureWorks;Integrated Security=SSPI;"
         providerName="System.Data.SqlClient" />
</connectionStrings>

And then configure Unity to use the type converter to get an IDbConnection instance from the connection name:

<types>
    <type type="MyProject.IRepository, MyProject, Version=1.0.0.0, Culture=neutral"
          mapTo="MyProject.DefaultRepository, MyProject, Version=1.0.0.0, Culture=neutral">
        <lifetime type="transient" />
        <typeConfig>
            <constructor>
                <param name="connection" parameterType="IDbConnection">
                    <value value="AdventureWorks" type="IDbConnection" typeConverter="DbConnectionNameTypeConverter" />
                </param>
            </constructor>
        </typeConfig>
    </type>
</types>

And bingo! We get all of the Unity goodness from the previous post but reuse the existing configuration section to centralise the connection settings!

Posted by stuartle | 3 Comments
Filed under: ,

Creating database connections with Unity

I was adding dependency injection to an existing project and opted to use Unity configured via the application configuration file. As I was running through the configuration, I hit a type that required a  database connection which it took in as an IDbConnection reference in the constructor so I added the following config under the container element:

<types>
    <type type="MyProject.IRepository, MyProject, Version=1.0.0.0, Culture=neutral"
          mapTo="MyProject.DefaultRepository, MyProject, Version=1.0.0.0, Culture=neutral">
        <lifetime type="transient" />
        <typeConfig>
            <constructor>
                <param name="connection" parameterType="IDbConnection">
                    <dependency />
                </param>
            </constructor>
        </typeConfig>
    </type>
</types>

(Before going any further, I should point out that I’ve added a type alias to the config for IDbConnection to save entering “System.Data.IDbConnection, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089” each time.)

If you’re not familiar with the configuration file options for Unity, each type element tells Unity what to do when that type is requested. In the case of IRepository the mapTo attribute instructs Unity to create an instance of DefaultRepository. The typeConfig section is used to specify how you want Unity to create the type and in this case we are instructing it to use the constructor that takes a single parameter of type IDbConnection. The dependency sub-element tells Unity to use itself to resolve the value for the IDbConnection parameter, so we need to add that to the config:

<types>
    <type type="MyProject.IRepository, MyProject, Version=1.0.0.0, Culture=neutral"
          mapTo="MyProject.DefaultRepository, MyProject, Version=1.0.0.0, Culture=neutral">
        <lifetime type="transient" />
        <typeConfig>
            <constructor>
                <param name="connection" parameterType="IDbConnection">
                    <dependency />
                </param>
            </constructor>
        </typeConfig>
    </type>
    <type type="IDbConnection" 
          mapTo="SqlConnection" >
        <typeConfig>
            <constructor>
                <param name="connectionString" parameterType="System.String">
                    <value value="Data Source=(local);Database=AdventureWorks;Integrated Security=SSPI;" />
                </param>
            </constructor>
        </typeConfig>
    </type>
</types>

We’ve now given Unity enough information to resolve the IRepository type and wire up the IDbConnection parameter in the constructor. One problem with this config is that whenever we try to resolve an IDbConnection we’re going to get a connection to AdventureWorks and my application needs a couple of different database connections. Fortunately Unity provides for this situation and we can add a name to the type mapping. So the IDbConnection specification becomes:

<type type="IDbConnection" 
          mapTo="SqlConnection" 
          name="AdventureWorksConnection">

and we can now refer to this type by name in the parameter dependency:

<dependency name="AdventureWorksConnection" />

This allows us to define multiple connection entries that we simply refer to by name when we need to. Using this approach, the same connection details can be referenced in multiple places in the config so connecting to a different server or database is simply a case of changing the connection string in a single place.  Also, assuming our repository class is able to deal with multiple database providers we can simply switch out the provider by changing the type Unity is creating for us (currently SqlConnection).

There’s lots more to Unity and for more information the Introduction to Unity page on MSDN is a good place to start. Next time we’ll take advantage of some of the flexibility of Unity to fix an something that I don’t really like about the above solution.

Posted by stuartle | 3 Comments
Filed under: ,

Microsoft AutoCollage 2008

I just thought I’d mention that Microsoft AutoCollage 2008 has been released. It is based on research from Microsoft Research in Cambridge and allows you to automatically create collages of images (not that you’d have guessed it from the name ;-) ). You can find out more, see example images, and download a free 30-day trial version from http://research.microsoft.com/AutoCollage (you can follow the download links to purchase it at the Microsoft online store). There are lots of great examples on the AutoCollage page, but I thought I’d add a personal collage…

2_AutoCollage_11_Images_2 (click to enlarge)

 

In case you’re wondering, the collage is of James  - the recent arrival to the Leeks clan :-D

Posted by stuartle | 2 Comments
More Posts Next page »
 
Page view tracker