.NET Zone is brought to you in partnership with:

I am developer and technology maniac who is working on Microsoft and PHP technologies. I have ASP.NET MVP title and I hold MCAD, MCSD and MCTS certificates. When I have free time I usually play with new technologies, hack something, read books, participate in communities and speak in events. I am also active blogger and my ASP.NET blog is the place you can find some interesting reading about my discoveries and personal thoughts. Gunnar is a DZone MVB and is not an employee of DZone and has posted 142 posts at DZone. You can read more from them at their website. View Full User Profile

Improved Version of ASP.NET CheckBox List Values Collection Method

07.05.2013
| 2993 views |
  • submit to reddit

In my last post about ASP.NET MVC checkbox list I came up with solution that makes it easy to update values in collection based on what was selected by user. I made some more progress meanwhile and here you can find improved version of collection update that breaks base class dependencies intoduced by previous solution.

Problem with previous solution

Signature to collection update method in my last solution was this:

public static void UpdateCollectionFromModel<T>(
 this ICollection<T> domainCollection, 
 IQueryable<T> objects, 
 int[] newValues) where T : BaseEntity

If you take quick look at this method signature it seems like okay but when digging deeper we will find some bad dependencies here:

  • we can use this extension method only with classes that inherit from BaseEntity,
  • We can use only integer keys,
  • Method forces also BaseEntity to use integer keys.

If you take a look at method body in previous checkbox list solution you will find one more requirement that solution forces to BaseEntity – it must define property called Id.

Main problems are:

  • not all business classes have identity property of type integer (don’t be surprised if you also meet types like long and Guid),
  • not all business classes define their identity with Id property.

If we can solve these problems then we have really generic solution that doesn’t depend on identity types and properties anymore.

Breaking dependencies

All problems above lead us away from Separation of Concerns (SoC) principle. Our domain layer implementation sneaks in even if we use model classes and we require all parts of our solution to accept the restricting knowledge. Simplest way to get base class and identity types away from this method is to move some responsibilities away from method.

My solution is actually simple:

  • we turn identities from integer to generic so we can accept all types of identities and not only integers.
  • we move code that finds object by id away from our method using Func that takes generic id and returns object of type T.

Here is the solution:

public static void UpdateCollectionFromModel<T, U>(this ICollection<T> domainCollection, 
 Func<U, T> objects, 
 U[] newValues) where T : class
{
    var newObjects = new List<T>();
    foreach (var newValue in newValues)
    {
        var newObject = objects(newValue);
        if (newObject != null)
            newObjects.Add(newObject);
    }
 
    for (var i = domainCollection.Count - 1; i >= 0; i--)
    {
        var domainObject = domainCollection.ElementAt(i);
        if (!newObjects.Contains(domainObject))
            domainCollection.Remove(domainObject);
    }
 
    foreach (var newObject in newObjects)
    {
        if (domainCollection.Contains(newObject))
            continue;
 
        domainCollection.Add(newObject);
    }
}

This is how I call this method when I update tags collection of event in my events application:

evt.Tags.UpdateCollectionFromModel(
    i => Context.Tags.FirstOrDefault(t => t.Id == i), 
    model.TagIds);

It is a little bit more code but this code is free of problems I listed in the beginning of this posting.

Conclusion

As previous version of checkbox list value collecting code forced restrictions to classes and identity types I worked out better solution that is more generic and doesn’t force code user to change his or her current classes. We got rid of integer id-s by using generic id-s and moving object finding out from our method gave us code that uses only collections and objects. Although calling the new version of method means some more code we don’t have bad dependencies anymore and we can use the same method also in other applications.

Related Posts

The post Improved version of ASP.NET checkbox list values collecting method appeared first on Gunnar Peipman - Programming Blog.

Published at DZone with permission of Gunnar Peipman, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)