Saturday, November 29, 2008

Linq is Cool, but…

Linq is great, got to love its ability to query object structures. In the following examples that I’ll show you I am only touching the abilities of Linq. And as you can see it is capable of doing some really cool things, but it comes at a price…

But first here is the basic object structure I use in the example:

Multiple classes
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
using System.Collections.Generic;

namespace LinqIsCool
{
    public class DataStructure
    {
        public readonly Dictionary<string, Author> Authors;
        public readonly List<Blog> Blogs;
        public readonly Dictionary<string, Post> Posts;

        public DataStructure()
        {
            Authors = new Dictionary<string, Author>
            {
                {"mark",   new Author("Mark Nijhof")},
                {"mona",   new Author("Mona Nijhof")},
                {"milo",   new Author("Milo Nijhof")},
                {"thalia", new Author("Thalia Nijhof")}
            };
            Posts = new Dictionary<string, Post>
            {
                {"post0", new Post("Tech talk 1",   Authors["mark"])},
                {"post1", new Post("Tech talk 2",   Authors["mark"])},
                {"post2", new Post("Tech talk 3",   Authors["mark"])},
                {"post3", new Post("Family talk 1", Authors["mona"])},
                {"post4", new Post("Tech talk 4",   Authors["mark"])},
                {"post5", new Post("Family talk 2", Authors["mona"])},
                {"post6", new Post("Tech talk 5",   Authors["mark"])},
                {"post7", new Post("Tech talk 6",   Authors["mark"])},
                {"post8", new Post("Family talk 2", Authors["mark"])},
                {"post9", new Post("Family talk 3", Authors["milo"])}
            };

            Blogs = new List<Blog>
            {
                new Blog("Blog.Fohjin.com", Authors["mark"]) 
                { 
                    Posts = new List<Post>
                    {
                        Posts["post0"],
                        Posts["post1"],
                        Posts["post2"],
                        Posts["post4"],
                        Posts["post6"],
                        Posts["post7"],
                        Posts["post8"]
                    }
                },
                new Blog("KidsTalk.Nijhof.com", Authors["mark"]) 
                { 
                    Posts = new List<Post>
                    {
                        Posts["post9"]
                    }
                },
                new Blog("Family.Nijhof.com", Authors["mona"])
                { 
                    Posts = new List<Post>
                    {
                        Posts["post3"],
                        Posts["post5"],
                        Posts["post8"],
                        Posts["post9"]
                    }
                }
            };
        }
    }

    public class Author
    {
        public string AuthorName { get; set; }
        public Author(string name)
        {
            AuthorName = name;
        }
    }

    public class Blog
    {
        public string BlogName { get; set; }
        public Author Owner { get; set; }
        public IList<Post> Posts { get; set; }
        public Blog(string name, Author owner)
        {
            BlogName = name;
            Owner = owner;
        }
    }

    public class Post
    {
        public string Title { get; set; }
        public Author Author { get; set; }
        public Post(string title, Author author)
        {
            Title = title;
            Author = author;
        }
    }
}


Wow that was long. Now the code below will actually show you several examples of using Linq, look at the comments for an explanation:

class LinqExamples
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
using System;
using System.Collections.Generic;
using System.Linq;

namespace LinqIsCool
{
    public class LinqExamples
    {
        private readonly DataStructure dataStructure;

        public LinqExamples()
        {
            dataStructure = new DataStructure();
        }

        /// <summary>
        /// Parses the data structure to find Authors that do not own a Blog
        /// How does it work:
        /// The Linq query is joining all the available Authors with the Blogs connecting 
        /// the Author with the Blog.Owner place the results in blogAuthors. The
        /// DefaultIfEmpty operator supplies a default element for an empty sequence,
        /// which in our example means that if there is no matching Blog for an Author it
        /// will return null. Then we specify to only select the objects where blogAuthor
        /// is null, so in effect only selecing Authors that have no Blog
        /// </summary>
        public void GetAuthorsThatDoNotOwnABlog()
        {
            var authors = 
            (
                from author in dataStructure.Authors.Values
                join blog in dataStructure.Blogs on author equals blog.Owner into blogAuthors
                    from blogAuthor in blogAuthors.DefaultIfEmpty()
                    where blogAuthor == null
                select author
            ).ToList();

            authors.ForEach(x => Console.WriteLine("- " + x.AuthorName));
        }

        /// <summary>
        /// Parses the data structure to find the number of Blogs an Authors owns
        /// How does it work:
        /// Selects every Author from the dataStructure.Authors.Values list and adds a Blogs
        /// List that gets its content from a sub Ling Query that basically selects all the 
        /// Blogs from the current Author and returns the Count for it
        /// </summary>
        public void GetNumberOfBlogsPerAuthor()
        {
            var authors = 
            (
                from author in dataStructure.Authors.Values
                select new
                {
                    _Autor = author,
                    _Blogs = 
                    (
                        from blog in dataStructure.Blogs
                        where blog.Owner == author
                        select blog
                    ).ToList().Count()
                }
            ).ToList();

            authors.ForEach(x => Console.WriteLine("- " + x._Autor.AuthorName + " owns " + x._Blogs + " blogs"));
        }

        /// <summary>
        /// Parses the data structure to find the actual Blogs an Authors owns
        /// How does it work:
        /// Selects every Author from the dataStructure.Authors.Values list and adds a Blogs
        /// List that gets its content from a sub Ling Query that basically selects all the 
        /// Blogs from the current Author and returns the List
        /// </summary>
        public void GetBlogsPerAuthor()
        {
            var authors = 
            (
                from author in dataStructure.Authors.Values
                select new
                {
                    _Autor = author,
                    _Blogs = 
                    (
                        from blog in dataStructure.Blogs
                        where blog.Owner == author
                        select blog
                    ).ToList()
                }
            ).ToList();

            authors.ForEach(x =>
            {
                Console.Write("- " + x._Autor.AuthorName + " owns ");
                x._Blogs.ForEach(y => Console.Write(y.BlogName + " "));
                Console.WriteLine();
            });
        }

        /// <summary>
        /// Parses the data structure to find specific Posts that belong to a specific Blog
        /// How does it work:
        /// First the Linq query specifies that it will use both dataStructure.Posts and
        /// dataStructure.Blogs. Then it specifies that the Blog should be the same as
        /// selectedBlog, the next line specifies that the resulting Posts should be part of 
        /// the selected Blog.Posts list and the final step is to specify that the resulting 
        /// Posts should be part of the provided list requestedPostIds. Then it selects the Post
        /// </summary>
        public void GetSpecificPostsFromSpecificBlog()
        {
            var requestedPostIds = new List<string> {"post0", "post1", "post9"};
            var selectedBlog = dataStructure.Blogs[0];

            var selectedPosts = 
            (
                from post in dataStructure.Posts
                from blog in dataStructure.Blogs
                where
                    blog == selectedBlog
                    && blog.Posts.Contains(post.Value)
                    && requestedPostIds.Contains(post.Key)
                select post.Value
            ).ToList();

            selectedPosts.ForEach(x => Console.WriteLine("- " + x.Title + " by " + x.Author.AuthorName));
        }

        /// <summary>
        /// Parses the data structure to find Posts from a specifies Author on a Blog where the Author is not the Owner
        /// How does it work:
        /// First the Linq query specifies that it will use both dataStructure.Posts and
        /// dataStructure.Blogs. Then it specifies that the Post should be the same as
        /// requestedAuthor, the next line specifies that the blog.Owner should not be part of 
        /// the same as requestedAuthor and the final step is to specify that the resulting 
        /// Posts should be part of the Posts list of the current Blog. Then is selects the 
        /// Post and the Blog
        /// </summary>
        public void GetPostsFromSpecificAuthorWhereNotBlogOwner()
        {
            var requestedAuthor = dataStructure.Authors["mark"];

            var selectedPosts = 
            (
                from post in dataStructure.Posts
                from blog in dataStructure.Blogs
                where
                    post.Value.Author == requestedAuthor
                    && blog.Owner != requestedAuthor
                    && blog.Posts.Contains(post.Value)
                select new
                {
                    post.Value, 
                    blog
                }
            ).ToList();

            selectedPosts.ForEach(x => 
                Console.WriteLine("- " + 
                    x.Value.Title + " by " + 
                    x.Value.Author.AuthorName + " on " + 
                    x.blog.BlogName));
        }
    }
}


Now we finally get to the part where we talk about the downside of Linq queries, you really quickly run into the risk that your code becomes unreadable. So when you do write some complex Linq queries I would suggest you also write proper comments use understandable variable names and perhaps split the Linq query into multiple Linq queries. Below here is the output when running the methods:

GetAuthorsThatDoNotOwnABlog()
- Milo Nijhof
- Thalia Nijhof

GetNumberOfBlogsPerAuthor()
- Mark Nijhof owns 2 blogs
- Mona Nijhof owns 1 blogs
- Milo Nijhof owns 0 blogs
- Thalia Nijhof owns 0 blogs

GetBlogsPerAuthor()
- Mark Nijhof owns Blog.Fohjin.com KidsTalk.Nijhof.com
- Mona Nijhof owns Family.Nijhof.com
- Milo Nijhof owns
- Thalia Nijhof owns

GetSpecificPostsFromSpecificBlog()
- Tech talk 1 by Mark Nijhof
- Tech talk 2 by Mark Nijhof

GetPostsFromSpecificAuthorWhereNotBlogOwner()
- Family talk 2 by Mark Nijhof on Family.Nijhof.com


Just for fun I “Alt + Enter”-ed a couple times, did some manual formatting and viola you have the same results but now using Lambda, remember I said something about readability?

class LambdaExamples
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
using System;
using System.Collections.Generic;
using System.Linq;

namespace LinqIsCool
{
    public class LambdaExamples
    {
        private readonly DataStructure dataStructure;

        public LambdaExamples()
        {
            dataStructure = new DataStructure();
        }

        /// <summary>
        /// Parses the data structure to find Authors that do not own a Blog
        /// How does it work:
        /// The Linq query is joining all the available Authors with the Blogs connecting 
        /// the Author with the Blog.Owner place the results in blogAuthors. The
        /// DefaultIfEmpty operator supplies a default element for an empty sequence,
        /// which in our example means that if there is no matching Blog for an Author it
        /// will return null. Then we specify to only select the objects where blogAuthor
        /// is null, so in effect only selecing Authors that have no Blog
        /// </summary>
        public void GetAuthorsThatDoNotOwnABlog()
        {
            var authors = 
            (
                dataStructure.Authors.Values.GroupJoin(
                    dataStructure.Blogs, 
                    author => author, 
                    blog => blog.Owner,
                    (author, blogAuthors) => new {author, blogAuthors}
                ).SelectMany(
                    @t => @t.blogAuthors.DefaultIfEmpty(), 
                    (@t, blogAuthor) => new {@t, blogAuthor}
                ).Where(
                    @t => @t.blogAuthor == null
                ).Select(
                    @t => @t.@t.author
                )
            ).ToList();

            authors.ForEach(x => Console.WriteLine("- " + x.AuthorName));
        }

        /// <summary>
        /// Parses the data structure to find the number of Blogs an Authors owns
        /// How does it work:
        /// Selects every Author from the dataStructure.Authors.Values list and adds a Blogs
        /// List that gets its content from a sub Ling Query that basically selects all the 
        /// Blogs from the current Author and returns the Count for it
        /// </summary>
        public void GetNumberOfBlogsPerAuthor()
        {
            var authors = 
            (
                dataStructure.Authors.Values.Select(
                    author => new 
                    { 
                        _Autor = author, 
                        _Blogs =
                        (
                            dataStructure.Blogs.Where(
                                blog => blog.Owner == author
                            )
                        ).ToList().Count()
                    })
            ).ToList();

            authors.ForEach(x => Console.WriteLine("- " + x._Autor.AuthorName + " owns " + x._Blogs + " blogs"));
        }

        /// <summary>
        /// Parses the data structure to find the actual Blogs an Authors owns
        /// How does it work:
        /// Selects every Author from the dataStructure.Authors.Values list and adds a Blogs
        /// List that gets its content from a sub Ling Query that basically selects all the 
        /// Blogs from the current Author and returns the List
        /// </summary>
        public void GetBlogsPerAuthor()
        {
            var authors = 
            (
                dataStructure.Authors.Values.Select(
                    author => new
                    {
                        _Autor = author,
                        _Blogs =
                        (
                            dataStructure.Blogs.Where(
                                blog => blog.Owner == author
                            )
                        ).ToList()
                    }
                )
            ).ToList();

            authors.ForEach(x =>
            {
                Console.Write("- " + x._Autor.AuthorName + " owns ");
                x._Blogs.ForEach(y => Console.Write(y.BlogName + " "));
                Console.WriteLine();
            });
        }

        /// <summary>
        /// Parses the data structure to find specific Posts that belong to a specific Blog
        /// How does it work:
        /// First the Linq query specifies that it will use both dataStructure.Posts and
        /// dataStructure.Blogs. Then it specifies that the Blog should be the same as
        /// selectedBlog, the next line specifies that the resulting Posts should be part of 
        /// the selected Blog.Posts list and the final step is to specify that the resulting 
        /// Posts should be part of the provided list requestedPostIds. Then it selects the Post
        /// </summary>
        public void GetSpecificPostsFromSpecificBlog()
        {
            var requestedPostIds = new List<string> {"post0", "post1", "post9"};
            var selectedBlog = dataStructure.Blogs[0];

            var selectedPosts = 
            (
                dataStructure.Posts.SelectMany(
                    post => dataStructure.Blogs, 
                    (post, blog) => new {post, blog}
                ).Where(
                    @t => @t.blog == selectedBlog
                          && @t.blog.Posts.Contains(@t.post.Value)
                          && requestedPostIds.Contains(@t.post.Key)
                ).Select(
                    @t => @t.post.Value
                )
            ).ToList();

            selectedPosts.ForEach(x => Console.WriteLine("- " + x.Title + " by " + x.Author.AuthorName));
        }

        /// <summary>
        /// Parses the data structure to find Posts from a specifies Author on a Blog where the Author is not the Owner
        /// How does it work:
        /// First the Linq query specifies that it will use both dataStructure.Posts and
        /// dataStructure.Blogs. Then it specifies that the Post should be the same as
        /// requestedAuthor, the next line specifies that the blog.Owner should not be part of 
        /// the same as requestedAuthor and the final step is to specify that the resulting 
        /// Posts should be part of the Posts list of the current Blog. Then is selects the 
        /// Post and the Blog
        /// </summary>
        public void GetPostsFromSpecificAuthorWhereNotBlogOwner()
        {
            var requestedAuthor = dataStructure.Authors["mark"];

            var selectedPosts = 
            (
                dataStructure.Posts.SelectMany(
                    post => dataStructure.Blogs, 
                    (post, blog) => new
                    {
                        post, blog
                    }
                ).Where(
                    @t => @t.post.Value.Author == requestedAuthor
                          && @t.blog.Owner != requestedAuthor
                          && @t.blog.Posts.Contains(@t.post.Value)
                ).Select(
                    @t => new
                    {
                        @t.post.Value,
                        @t.blog
                    }
                )
            ).ToList();

            selectedPosts.ForEach(x => 
                Console.WriteLine("- " + 
                    x.Value.Title + " by " + 
                    x.Value.Author.AuthorName + " on " + 
                    x.blog.BlogName));
        }
    }
}


Hope you enjoyed this.

-Mark

Wednesday, November 26, 2008

Being Specific with your Generics – Visitor Pattern without the Visitors

Generics are very useful when you have a particular functionality / logic that you want to apply on different types. Instead of having to duplicate the functionality for all your types you can put it in a generic class / method and have all the different types use it. One of the most used examples of this I think is it List<T> this is basically a strongly typed list that can be used for any type, and it works the same for any type.

This is great, but… (yes there is a but), what if what you have is 90% generic and 10% specific to the provided type, lets walk through an example that I encountered when working with Castle ActiveRecord. Each Business Data Object that you want to persist to the database using Castle ActiveRecord needs to be derived from ActiveRecordBase<T> where T is the derived class. This gives certain default functionality to each derived object like Save(). I’ll use the Blog and Post analogy that Ayende uses a lot too as it makes sense.

class Blog : ActiveRecordBase
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using Castle.ActiveRecord;

namespace Fohjin.SpecificWithGenerics
{
    [ActiveRecord]
    public class Blog : ActiveRecordBase<Blog>
    {
        [PrimaryKey]
        public virtual int Id { get; set; }
        [Property]
        public string Name { get; set; }
        [Property]
        public string Author { get; set; }
        [HasMany(typeof(Post))]
        public IList<Post> Posts { get; set; }
    }
}



Post : ActiveRecordBase
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
using Castle.ActiveRecord;

namespace Fohjin.SpecificWithGenerics
{
    [ActiveRecord]
    public class Blusing Castle.ActiveRecord;

namespace Fohjin.SpecificWithGenerics
{
    [ActiveRecord]
    public class Post : ActiveRecordBase<Post>
    {
        [PrimaryKey]
        public virtual int Id { get; set; }
        [Property]
        public virtual string PostId { get; set; }
        [BelongsTo("BlogId")]
        public virtual Blog Blog { get; set; }
        [Property]
        public string Title { get; set; }
        [Property]
        public string Content { get; set; }
    }
}
og : ActiveRecordBase<Blog>
    {
        [PrimaryKey]
        public virtual int Id { get; set; }
        [Property]
        public string Name { get; set; }
        [Property]
        public string Author { get; set; }
        [HasMany(typeof(Post))]
        public IList<Post> Posts { get; set; }
    }
}


Now that this is working fine, we wanted to add some generic functionality to both classes, a GetOrCreate (object id) method, which as the name already specifies tries to get an items based on the provided Id from the datebase and if that fails create a new one. So I created a RepositoryItemBase<T> class:

class RepositoryItemBase : ActiveRecordBase where T : class, new()
1
2
3
4
5
6
7
8
9
10
11
12
13
using Castle.ActiveRecord;

namespace Fohjin.SpecificWithGenerics
{
    public class RepositoryItemBase<T> : ActiveRecordBase<T> where T : class, new()
    {
        public T GetOrCreate(object id)
        {
            return Find(id) ?? new T();
        }
    }
}


So instead of having our Business Data Objects inherit from ActiveRecordBase<T> they will inherit from RepositoryItemBase<T> that inherits from ActiveRecordBase<T> again. Thus in affect extending the ActiveRecordBase<T> with the GetOrCreate functionality.

Now this works all fine, except that our Post class has a PostId which is not the PrimaryKey, but this is the key that is used to find the blog posts. This means that we need to specifically handle some generic types different than others. In my example I only have one extension and you could argue to add that method to the actual Business Data Objects, but in our solution we have many more Business Data Objects and there are only a few different GetOrCreate variants. And there are more generic extension methods. I could also create new derived objects from RepositoryItemBase<T> and have the specific functionality in there, but that didn’t look to appealing to me. So here is my implementation using an adapted Visitor Pattern using a bit like a very simple IoC container and Delegates.

class RepositoryItemBase : ActiveRecordBase where T : class, new()
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
using System;
using System.Collections.Generic;
using Castle.ActiveRecord;

namespace Fohjin.SpecificWithGenerics
{
    public class RepositoryItemBase<T> : ActiveRecordBase<T> where T : class, new()
    {
        private readonly IDictionary<Type, Func<object, T>> delegatesByType;

        public RepositoryItemBase()
        {
            delegatesByType = new Dictionary<Type, Func<object, T>>();
            InitializeDelegatesByType();
        }

        public T GetOrCreate(object id)
        {
            if (!delegatesByType.ContainsKey(typeof(T)))
                throw new TypeLoadException("The provided type \"{0}\" is not supported!", typeof(T).ToString());

            return delegatesByType[typeof(T)].Invoke(id);
        }

        private void InitializeDelegatesByType()
        {
            delegatesByType.Add(typeof(Blog), x => Find(x) ?? new T());
            delegatesByType.Add(typeof(Post), x =>
            {
                var posts = FindAllByProperty("PostId", x);
                if (posts.Length > 0)
                {
                    return posts[0];
                }
                return new Post { PostId = x.ToString() } as T;
            });
        }
    }
}


As you can see I added a IDictionary<Type, Func<object, T>> this is for the IoC principle but instead of returning an object for a specific type it returns a function. This is where the Visitor Pattern comes into play, you define specific logic for each type, just like you would define a Visitor for each type, but instead of creating the different Visitor classes I defined different delegates with the same signature.

edit
I got some comments from people about something I did know, but maybe didn’t want to see :) the class RepositoryItemBase is violating the Open Closed Principle (OCP). As I also explain in a comment to Raymond we moved away from Castle ActiveRecord:

The main reason we were using Castle ActiveRecord was because we could configure our NHibernate mappings using Attributes instead of writing XML. But how Castle ActiveRecord places all the extra logic in the data containers was bothering us on different areas. I want the application to have a single point to do any data related tasks so I ended up with ugly methods that were like this: public class Repository { public void Save(ActiveRecordBase entity) { entity.Save(); } }

So I re-factored Castle ActiveRecord out of the solution and started using Fluent NHibernates AutoMap functionality for the mapping and DB schema generation (while developing) and plain NHibernate for the persistence tasks, much cleaner.

I also re-factored the non primary key name to be SourceId and placed this in the following interface:

interface IRepositoryItemWithSourceId
1
2
3
4
5
6
7
namespace Fohjin.SpecificWithGenerics
{
    public interface IRepositoryItemWithSourceId
    {
        string SourceId { get; set; }
    }
}

Now all the Business Data Objects that have this special Id need to inherit from this interface, and that lets me do to following thing:

class Repository : IRepository
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
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;
using FluentNHibernate.Framework;
using InfoDoc.Server.BL.BDO.Interfaces;
using NHibernate;
using NHibernate.Criterion;

namespace Fohjin.SpecificWithGenerics
{
    public class Repository : IRepository
    {
        private readonly ISessionSource sessionSource;

        public Repository(ISessionSource source)
        {
            sessionSource = source;
        }
        public IList<T> Query<T>(Expression<Func<T, bool>> function)
        {
            ISession session = sessionSource.CreateSession();
            FluentNHibernate.Framework.IRepository nHibernateRepository = new FluentNHibernate.Framework.Repository(session);
            return nHibernateRepository.Query(function);
        }

        public T GetOrCreate<T>(object id) where T : class, IRepositoryItemWithSourceId, new()
        {
            var items = Query<T>(r => r.SourceId == id.ToString());
            return items.Count > 0 ? items[0] : new T { SourceId = id.ToString() };
        }
    }
}


As you can see now we are talking Generics again and don't have any dirty techniques to threat a generic value in a specific way. I do plan to explore the technique that Raymond suggested as well as a technique John suggested in a feature post, but for this problem the current solution is probably the best.

I hope you found this useful and as always if it can be improved please let me know.

-Mark

NNUG – TFS With Terje Sandstrøm

Last night was again a very interesting NNUG meeting this time with Terje Sandstrøm and the topic this day was TFS and how to use TFS in a Continuous Integration process. There were many things that I didn’t know yet and many Aha moments during the presentation. I also heard from other attendees that they would be applying the newly learned knowledge in their own environment right away.

And as usual the day didn’t end after the presentation, a couple of guys went with Terje to a pub to get some very interesting discussions going, I remember going home quite late. You can follow Terje on his blog http://geekswithblogs.net/terje/Default.aspx

-Mark

Tuesday, November 25, 2008

Announcing Isolator for Sharepoint : Unit testing for sharepoint made easier (and a free license!)

Typemock are offering their new product for unit testing SharePoint called Isolator For SharePoint, for a special introduction price. it is the only tool that allows you to unit test SharePoint without a SharePoint server. To learn more click here.

The first 50 bloggers who blog this text in their blog and tell us about it, will get a Full Isolator license, Free. for rules and info click here.

This is a great change to gain some experiance with Typemock -Mark