Method chaining with deferring object creation

I have decided to write a couple of posts about how I used Method Chaining to help solve and better handle the creation of test data within my Unit Tests. This post and the example code via GitHub shows how I created test data using Method Chaining in a more generic form. There will be more posts to come regarding how this test data gets persisted into a in-memory database which will get used in XUnit Tests.

For my problem, I had to build up test data that will be used within a number of Unit Tests. Creating objects and assigning values to properties through Factory classes is considered a fairly normal approach, however being able to build up objects using method chaining gives me the flexibility to create objects with different characteristics.

For example, var foo = MyFooBuilder.Create().WithName(“My Foo”).WithAge(5).WithCar(“Audi”).Build(). This allows me to build up a foo object using a nice fluent chaining of methods compared to var foo = new Foo() { Name = “My Foo”, Age = 5, Car = “Audi” }. This allows me to keep all the Foo created code in a nice and tidy builder class which provides the flexibility to extend the builder to introduce new characteristics in the future.

What I ended up creating was a generic builder class that allows me to use a object of type T, build up a set of actions to get a newly created object. for example, var foo = MyBuilder.Create().WithProperty(new { Name = “MyPropertyName”, Value = “MyValue” }).Build();

You can view my builder class at https://github.com/codelabnz/BuilderExample

The call is ambiguous between the following methods or properties: ‘Umbraco.Web.UmbracoHelper.Media

I was coding up a new template in the latest version of Umbraco v7 using Razor and discovered this error when trying to get a Media object from one of my properties of the current page.


The call is ambiguous between the following methods or properties: ‘Umbraco.Web.UmbracoHelper.Media(params int[])’ and ‘Umbraco.Web.UmbracoHelper.Media(params string[])’

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: The call is ambiguous between the following methods or properties: ‘Umbraco.Web.UmbracoHelper.Media(params int[])’ and ‘Umbraco.Web.UmbracoHelper.Media(params string[])’

My property was a Media Picker type which I made the assumption it was given me a Integer Node Id to the specific media object.

I started out with the following code:

1
@Umbraco.Media(CurrentPage.ProfileImage).umbracoFile

This caused the error above, so by converting it to a string using the .ToString() method, this caused the compiler to ignore the error and use the correct UmbracoHelper method.

1
@Umbraco.Media(CurrentPage.portfolio5Image.ToString()).umbracoFile

Upgrading MVC Project 2 to 4 and open it in VS 2012

I have an old MVC 2 project that works fine in VS 2010. However, if you try and open the project in VS 2012 you will get a “incompatible” error and left with no way to upgrade the project to VS 2012.

Here are some pointers to get it working (this is how I got it working for myself).

In VS2010, upgrade your MVC project to version 4. You need to follow the upgrade steps for upgrading to MVC 2 – 3 first.

http://www.asp.net/whitepapers/mvc3-release-notes#upgrading

Secondly, upgrade from MVC 3 to 4 using the following link.

http://www.asp.net/whitepapers/mvc4-release-notes#_Toc303253806

Once you have done this, you need to edit the project file of the working web application (i.e csproj). Firstly, open the solution in VS2012, the web project will not work but you can edit the project file directly in the IDE.

Make sure that you add the MVC 4 ProjectTypes GUID ({E3E379DF-F4C6-4180-9B81-6769533ABE47}) and remove the old MVC ProjectTypes GUID ({F85E285D-A4E0-4152-9332-AB1D724D3325}).

Here is a list of available GUIDS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Windows (C#) {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
Windows (VB.NET) {F184B08F-C81C-45F6-A57F-5ABD9991F28F}
Windows (Visual C++) {8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}
Web Application {349C5851-65DF-11DA-9384-00065B846F21}
Web Site {E24C65DC-7377-472B-9ABA-BC803B73C61A}
WCF {3D9AD99F-2412-4246-B90B-4EAA41C64699}
WPF {60DC8134-EBA5-43B8-BCC9-BB4BC16C2548}
XNA (Windows) {6D335F3A-9D43-41b4-9D22-F6F17C4BE596}
XNA (XBox) {2DF5C3F4-5A5F-47a9-8E94-23B4456F55E2}
XNA (Zune) {D399B71A-8929-442a-A9AC-8BEC78BB2433}
Silverlight {A1591282-1198-4647-A2B1-27E5FF5F6F3B}
ASP.NET MVC {F85E285D-A4E0-4152-9332-AB1D724D3325}
ASP.NET MVC 4 {E3E379DF-F4C6-4180-9B81-6769533ABE47}
Test {3AC096D0-A1C2-E12C-1390-A8335801FDAB}
Solution Folder {2150E333-8FDC-42A3-9474-1A3956D46DE8}

http://stackoverflow.com/questions/2911565/what-is-the-significance-of-projecttypeguids-tag-in-the-visual-studio-project-fi

From here you reload the project (after you save the project file) and a way you go.

Unit Testing ObjectResult

I came across an interesting scenario where I wanted to unit test an imported function in the Entity Framework. The initial problem is that an imported function generates code like this:

1
2
3
4
5
public virtual ObjectResult<MyObject> GetData()
        {
   
            return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<MyObject>("GetData");
        }

The key method here is the results are returned as the ObjectResult object which 1) cannot be mocked (using RhinoMocks) because it’s sealed. There are no constructors available to create concrete instances of the object. So the best solution I can come up with is to create a new interface and create two classes that implement the interface, one for the real application and one for unit testing. From here, the unit testing class which has the interface can return anything it likes i.e. fake objects while the other class can call the function import method and return the results.

Firstly, I create the interface

1
2
3
4
5
6
public partial interface IExtendedEntities
    {
       
        IEnumerable<MyObject> GetDataWrapper();

    }

Secondly, I create the class that will use this interface for the real application.

1
2
3
4
5
6
7
public partial class MyClassReal : DbContext, IExtendedEntities
    {
        public IEnumerable<MyObject> GetDataWrapper()
        {
            return this.GetData().AsEnumerable();
        }
    }

Thirdly, create the class that uses the interface for unit testing

1
2
3
4
5
6
7
public partial class MyClassFake : DbContext, IExtendedEntities
    {
        public IEnumerable<MyObject> GetDataWrapper()
        {
            return Builder<MyObject>.CreateListOfSize(10).Build();
        }
    }

When I’m implementing the logic, I can inject (using nInject) an object of the interface IExtendedEntities and call GetDataWrapper();

When unit testing, I can create a new MyClassFake object and return a list of test data. This gives me the control to create a test case of specific test data to be put through the method that gets called to return a set of results from the Imported Function.

Giving Enum’s descriptions

Enums are very good for giving descriptions to values especially numeric values. By default though a enum value name cannot have spaces. Look at the following which shows an example of no spaces between the first enum value name.

1
2
3
4
enum myEnum
{
   Icannothaveaspace = 1
}

A good way to solve this problem is to use the Description attribute from the System.ComponentModel namespace. We can use this attribute to give each enum value a descriptive meaning.

1
2
3
4
5
6
7
8
9
using System.ComponentModel;

 public enum MyEnum
    {
        [Description("Authorised Contact")]
        AuthorisedContact = 1,
        [Description("Assigned Contact")]
        CoauthorisedContact = 2
    }

From here we can create a extension method that uses reflection to get the description attribute for the selected enum value.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public static class Extensions
    {
        /// <summary>
        /// Get the description of a enum value using the description attribute
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string GetEnumDescription(this Enum value)
        {
            FieldInfo fi = value.GetType().GetField(value.ToString());

            DescriptionAttribute[] attributes =
                (DescriptionAttribute[])fi.GetCustomAttributes(
                typeof(DescriptionAttribute),
                false);

            if (attributes != null && attributes.Length > 0)
                return attributes[0].Description;
           
            return value.ToString();
        }
    }

To use this, just call GetEnumDescription to get the description of a enum value.

1
2
3
4
5
6
7
8
9
  using Extensions; //Make sure that you use this to get the extension method
 
  public myClass
  {
      public void foo()
      {
          var myDescription = MyEnumValue.GetEnumDescription();
      }
  }

Some useful Extension Methods

Back to basics…

A couple of useful Extension methods if you are checking if a string is a valid integer or decimal.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static bool IsInteger(this string value)
{
if (String.IsNullOrEmpty(value)) return false;
Int32 tmpNo;
return Int32.TryParse(value, out tmpNo);
}


public static bool IsDecimal(this string value)
{
if (String.IsNullOrEmpty(value)) return false;
Decimal tmpNo;
return Decimal.TryParse(value, out tmpNo);
}

To implement the Extension Methods:

1
2
3
4
5
6
7
8
9
var myString = "10.5";

if (myString.IsDecimal())

{

//Do something

}

OrderBy making null records come last Entity Framework and Linq

Ever want to sort your result set but make sure the records with a null sorting column appear last?
See the example below

1
2
3
4
5
6
7
8
9
10
var results = (from x in EntityObjectContext.MyTable
              select x
              into grp
              select new
              {
            mydata = grp,
            myid = grp.id,
            mysortingentity = grp.mysortingentity
              }
             ).OrderBy(x => sortingcolumn == null).ThenBy(x => x.mysortingentity.Name).ThenBy(x => x.myid);

Watch this space, this can easily be transformed into a Extension Method. Check out this link http://tahirhassan.blogspot.com/2010/06/linq-to-sql-order-by-nulls-last.html, this Extension method works for LinqToSQL.

Finding StoreGeneratedPattern value in EdmProperty in T4 Template

If you need to find out if a primary key in your conceptual model which is using the Identity value from the property StoreGeneratedPattern, you can use the following code: (NOTE: This is used within a T4 template)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
string inputFile = @"..\EntitiesModel.edmx";
EdmItemCollection ItemCollection = loader.CreateEdmItemCollection(inputFile);
string annotationNamespace = "http://schemas.microsoft.com/ado/2009/02/edm/annotation";

foreach (EntityType entity in ItemCollection.GetItems<EntityType>().OrderBy(e => e.Name)) {
   foreach (EdmProperty edmProperty in entity.Properties.Where(p => p.TypeUsage.EdmType is PrimitiveType && p.DeclaringType == entity)) {
 
      MetadataProperty storeGeneratedPatternProperty = null;
      edmProperty.MetadataProperties.TryGetValue(annotationNamespace + ":StoreGeneratedPattern", false, out storeGeneratedPatternProperty);

      if (storeGeneratedPatternProperty != null && storeGeneratedPatternProperty.Value.ToString() == "Identity") {
         //We found an Identity property
      }
   }
}

Open XML – OLE Automation Date Issues

If you are exporting a date from C# to Excel using 2007, you probably will use the following:

1
Math.Round(DateTime.Now.ToOADate(), 12).ToString()

This exports the date as a OLE Automation date recognized by Excel 2007. How ever, in Excel 2010 this was causing issues, every time I exported to Excel 2010, it said that it has to repair my document and it never displayed the values correctly as dates.

Because I was using Open XML to generate the markup, Excel 2010 has been support for Open XML. I got around the problem of using:

1
DateTime.Now.ToString("yyyy-MM-dd'T'HH:mm:ss.fffffffzzz");

This exports the date as a XML Date format.
Hope this helps anyone who has the same problem!

Fixing the EF Tracing and Caching Provider Wrapper Issue

If you have been using the Tracing and Caching Provider Wrappers for the ADO.NET Entity Framework 4.0, you might of come across this error message when creating POCO objects, adding them to a Data Context and commiting them to the database using the Caching Wrapper:

[NotImplementedException: The method or operation is not implemented.]
   EFCachingProvider.EFCachingDataReaderCacheWriter.GetName(Int32 ordinal) in EFCachingProvider\EFCachingDataReaderCacheWriter.cs:109
   System.Data.Mapping.Update.Internal.DynamicUpdateCommand.Execute(UpdateTranslator translator, EntityConnection connection, Dictionary`2 identifierValues, List`1 generatedValues) +8118458
   System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter) +267

Line 107:        public override string GetName(int ordinal)
Line 108:        {
Line 109:            throw new NotImplementedException();
Line 110:        }
Line 111:

Basically, the author’s of the code have created a wrapper for the DBDataReader class and have not implement the override methods.   This can be fixed by calling the Wrapper DataReader object methods.  This is what I have modified in the EFCachignDataReaderCacheWriter.cs file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
using System;
using System.Data;
using System.Data.Common;
using EFCachingProvider.Caching;

namespace EFCachingProvider
{
///
/// Implementation of the  which reads the results of another data reader
/// and stores a copy in the cache.
///
internal class EFCachingDataReaderCacheWriter : EFCachingDataReaderBase
{
private DbQueryResults queryResults = new DbQueryResults();
private DbDataReader wrappedReader;
private int maxRows;
private Action addToCache;

///
/// Initializes a new instance of the EFCachingDataReaderCacheWriter class.
///
///
<span> </span>The wrapped reader.         ///
<span> </span>The maximum number of rows which can be cached.         ///
The delegate used to add the result to the cache when the reader finishes.         public EFCachingDataReaderCacheWriter(DbDataReader wrappedReader, int maxRows, Action addToCache)
{
this.wrappedReader = wrappedReader;
this.addToCache = addToCache;
this.maxRows = maxRows;
}

///
/// Gets a value that indicates whether this  contains one or more rows.
///
///
/// true if the  contains one or more rows; otherwise false.
///
public override bool HasRows
{
get { return this.wrappedReader.HasRows; }
}

///
/// Gets the number of rows changed, inserted, or deleted by execution of the SQL statement.
///
///
///
/// The number of rows changed, inserted, or deleted. -1 for SELECT statements; 0 if no rows were affected or the statement failed.
///
public override int RecordsAffected
{
//get { throw new NotImplementedException(); }
get { return this.wrappedReader.RecordsAffected; }
}

///
/// Gets a value indicating whether the  is closed.
///
///
/// true if the  is closed; otherwise false.
///
public override bool IsClosed
{
//get { throw new NotImplementedException(); }
get { return this.wrappedReader.IsClosed; }
}

///
/// Gets a value indicating the depth of nesting for the current row.
///
///
///
/// The depth of nesting for the current row.
///
public override int Depth
{
//get { throw new NotImplementedException(); }
get { return this.wrappedReader.Depth; }
}

///
/// Gets name of the data type of the specified column.
///
///
The zero-based column ordinal.         ///
/// A string representing the name of the data type.
///
public override string GetDataTypeName(int ordinal)
{
//throw new NotImplementedException();
return this.wrappedReader.GetDataTypeName(ordinal);
}

///
/// Gets the data type of the specified column.
///
///
The zero-based column ordinal.         /// The data type of the specified column.
public override Type GetFieldType(int ordinal)
{
return this.wrappedReader.GetFieldType(ordinal);
}

///
/// Gets the name of the column, given the zero-based column ordinal.
///
///
The zero-based column ordinal.         /// The name of the specified column.
public override string GetName(int ordinal)
{
return this.wrappedReader.GetName(ordinal);
}

///
/// Gets the column ordinal given the name of the column.
///
///
The name of the column.         /// The zero-based column ordinal.
///
/// The name specified is not a valid column name.
///
public override int GetOrdinal(string name)
{
return this.wrappedReader.GetOrdinal(name);
}

///
/// Returns a  that describes the column metadata of the .
///
///
/// A  that describes the column metadata.
///
public override DataTable GetSchemaTable()
{
return this.wrappedReader.GetSchemaTable();
}

///
/// Advances the reader to the next result when reading the results of a batch of statements.
///
///
/// true if there are more result sets; otherwise false.
///
public override bool NextResult()
{
if (this.wrappedReader.NextResult())
{
this.queryResults = null;
return true;
}
else
{
return false;
}
}

///
/// Closes the  object.
///
public override void Close()
{
this.wrappedReader.Close();

if (this.queryResults != null)
{
this.addToCache(this.queryResults);
}
}

///
/// Advances the reader to the next record in a result set.
///
///
/// true if there are more rows; otherwise false.
///
public override bool Read()
{
if (this.wrappedReader.Read())
{
object[] values = new object[this.wrappedReader.FieldCount];

this.wrappedReader.GetValues(values);
SetValues(values);
if (this.queryResults != null)
{
this.queryResults.Rows.Add(values);
if (this.queryResults.Rows.Count &gt; this.maxRows)
{
this.queryResults = null;
}
}

return true;
}
else
{
return false;
}
}
}
}