0

I have bunch of data objects that I populate after getting data from a feed. The feed is unreliable and sometimes drops data. I need to merge the incoming data with the data that I already have. I am unable to figure out an easily extendable and scalable pattern for that.

For example, my datamodel has the following field

DataModelExample
{
    public string Name;
    public string Value;
    public string Extension;
}

If the feed drops the field Value, it is okay for me to pick data from an existing data object from cache and merge the two. I have a number of data objects with varying number of fields where this needs to be done.

Any ideas?

Patrick
  • 1,717
  • 7
  • 21
  • 28
user1542794
  • 137
  • 1
  • 12
  • How would you pick up a cached object? Would you use `Name` to match two objects together? – FishBasketGordo Aug 02 '12 at 15:07
  • I have cache with the key-value mapping. So an object with type DataModelExample will always have the key - DataModelExampleKey, which is what I would use to fetch data from the cache. – user1542794 Aug 02 '12 at 15:14

2 Answers2

3

One possible way:

You could change all your property definitions so they are all nullable.

For instance, if you have a public int MyInt { get; set; } property, change it to public int? MyInt { get; set; }

Then, after your object has been populated from your feed, you could iterate over all your properties using reflection (see How to loop through all the properties of a class?) and for each property, if the value is null (which means the feed drops the property), set it with a value that comes from your cache.

Community
  • 1
  • 1
ken2k
  • 48,145
  • 10
  • 116
  • 176
  • Thanks for your response. I am not keen to use reflection because of its perf cost. – user1542794 Aug 02 '12 at 15:16
  • 1
    @user1542794 Okay, but if one of your requirement is "I have a number of data objects with varying number of fields where this needs to be done", I don't see much possibilities without having to duplicate code – ken2k Aug 02 '12 at 15:23
  • @user1542794 you can still use the nullable technique to make it clear which values were dropped and then write the merge code yourself instead of using reflection. It will just be less maintainable – cordialgerm Aug 02 '12 at 15:28
  • @pickles Yes, it's all about maintainability. I would use reflection here, I suspect the OP is in a case of [premature-optimization](http://en.wikipedia.org/wiki/Program_optimization#When_to_optimize). – ken2k Aug 02 '12 at 15:38
  • The approach works quite well. However, I have been unable to get the design approved. The second I used the word 'Reflection' people gasped in disbelief. Still working on it. Thanks ken2k. – user1542794 Aug 20 '12 at 10:49
0

In lieu of reflection, which @ken2k suggested, you could create a group of classes that process your objects and merges the data from the cache if necessary. To minimize the number of such classes that you would need, I'd have them operate on an interface, which your data objects would implement.

public interface IDataModelExample
{
    string Name { get; set; }
    string Value { get; set; }
    string Extension { get; set; }
}

public class DataModelExampleMerger
{
    public IDataModelExample Merge(IDataModelExample dme)
    {
        var cachedDme = LoadFromCache(); // This would require the key of course.
                                         // I'll leave the implementation up to 
                                         // you.

        if (string.IsNullOrEmpty(dme.Name))
        {
            dme.Name = cachedDme.Name;
        }

        // Repeat similar if-block for all properties.

        return dme;
    }
}

You would need to write one merger class per data object interface, so this solution would require considerably more code than a reflection-based solution. I don't think you can get around the work. It's a trade-off: runtime performance versus overall coding time. Honestly, I would take the runtime performance hit unless your users start complaining, but it's up to you.

Remember, premature optimization is the root of all evil.

FishBasketGordo
  • 22,904
  • 4
  • 58
  • 91