Avatar

Blog (pg. 12)

  • Published on
    The following code shows an example of implementing the Microsoft AppFabric Caching mechanism (part of the Azure framework). I wanted a generic caching helper which can be used by calling code without too much effort or consideration for the internal workings, such as how data from different sources is partitioned (to avoid ID conflicts). The way I have done this is to the fully qualified type name, supplied by the generic parameter. In the event that the AppFabric server could not be contacted on startup, there is an alternative memory based cache, which allows the programmer to specify names of types which should not be included in the memory based cache.
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using Microsoft.ApplicationServer.Caching;
    using System.Text.RegularExpressions;
    
    namespace Common.FabricCache
    {
        public static class FabricCacheHelper
        {
    
            public static object SyncLock = new object();
            static DataCacheFactory myCacheFactory;
            static DataCache myFabricCache;
    
            static FabricCacheHelper()
            {
                PrepareClient();
            }
    
            public static T GetFromCache<T>(string key)
            {
                if (myFabricCache != null)
                {
                    //user the region per type and use the key as the identifier within that region
                    return (T)myFabricCache.Get(key, Regex.Replace(typeof(T).FullName, "[^a-z0-9]", "", RegexOptions.IgnoreCase));
                }
                else
                {
                    return (T)AlternateCache.Get(key, Regex.Replace(typeof(T).FullName, "[^a-z0-9]", "", RegexOptions.IgnoreCase));
                }
            }
    
            public static void AddToCache<T>(string key, T value)
            {
                if (value != null)
                {
                    if (myFabricCache != null)
                    {
                        //create a region per type and use the key as the identifier within that region
                        myFabricCache.CreateRegion(Regex.Replace(typeof(T).FullName, "[^a-z0-9]", "", RegexOptions.IgnoreCase));
                        myFabricCache.Put(key, value, Regex.Replace(typeof(T).FullName, "[^a-z0-9]", "", RegexOptions.IgnoreCase));
                    }
                    else
                    {
                        //create a region per type and use the key as the identifier within that region
                        AlternateCache.CreateRegion(Regex.Replace(typeof(T).FullName, "[^a-z0-9]", "", RegexOptions.IgnoreCase));
                        AlternateCache.Put(key, value, Regex.Replace(typeof(T).FullName, "[^a-z0-9]", "", RegexOptions.IgnoreCase));
                    }
                }
            }
    
            public static void RemoveFromCache<T>(string key)
            {
                if (myFabricCache != null)
                {
                    myFabricCache.Remove(key, Regex.Replace(typeof(T).FullName, "[^a-z0-9]", "", RegexOptions.IgnoreCase));
                }
                else
                {
                    AlternateCache.Remove(key, Regex.Replace(typeof(T).FullName, "[^a-z0-9]", "", RegexOptions.IgnoreCase));
                }
            }
    
            private static void PrepareClient()
            {
                //-------------------------
                // Configure Cache Client 
                //-------------------------
    
                //Define Array for 1 Cache Host
                List<DataCacheServerEndpoint> servers = new List<DataCacheServerEndpoint>(1);
    
                //Specify Cache Host Details 
                //  Parameter 1 = host name
                //  Parameter 2 = cache port number
                string fabricHost = System.Configuration.ConfigurationManager.AppSettings["FabricHost"];// = "localhost";
                int fabricPort = int.Parse(System.Configuration.ConfigurationManager.AppSettings["FabricPort"]); // 22233;
                servers.Add(new DataCacheServerEndpoint(fabricHost, fabricPort));
    
                //Create cache configuration
                DataCacheFactoryConfiguration configuration = new DataCacheFactoryConfiguration();
    
                //Set the cache host(s)
                configuration.Servers = servers;
    
                //Set default properties for local cache (local cache disabled)
                configuration.LocalCacheProperties = new DataCacheLocalCacheProperties();
    
                //Disable exception messages since this sample works on a cache aside
                DataCacheClientLogManager.ChangeLogLevel(System.Diagnostics.TraceLevel.Off);
    
                //Pass configuration settings to cacheFactory constructor
                myCacheFactory = new DataCacheFactory(configuration);
    
                //Get reference to named cache
                try
                {
                    string fabricCacheName = System.Configuration.ConfigurationManager.AppSettings["FabricCacheName"];
                    myFabricCache = myCacheFactory.GetCache(string.IsNullOrEmpty(fabricCacheName) ?  "myFabricCache" : fabricCacheName);
                }
                catch (Exception)
                {
                    //if anything goes wrong with the fabric, just carry on which will use the alternate method
                    myFabricCache = null;
                }
            }
    
            #region "Alternative Cache - Memory Based"
            private static class AlternateCache
            {
                private static Dictionary<string, Dictionary<string, object>> _alternateMemoryCache = new Dictionary<string, Dictionary<string, object>>();
    
                //some types are known to be large, so we wouldnt want them in the w3wp process memory of this alternative cache - they should be ignored (as if not cached)
                private static string[] _typeNameRegionRestrictions = new string[]
                {
                };
    
                internal static object Get(string key, string region)
                {
                    Dictionary<string, object> regionCache;
                    
                    if (_alternateMemoryCache.TryGetValue(region, out regionCache))
                    {
                        object value;
                        if (regionCache.TryGetValue(key, out value))
                        {
                            return value;
                        }
                    }
    
                    //wasnt in the cache
                    return null;
                }
    
                internal static void CreateRegion(string region)
                {
                    //is this region allowed, or are we blocking this type?
                    if (!IsRestrictedRegionName(region))
                    {
                        if (!_alternateMemoryCache.ContainsKey(region))
                            _alternateMemoryCache.Add(region, new Dictionary<string, object>());
                    }
                }
    
                internal static void Put(string key, object value, string region)
                {
                    Dictionary<string, object> regionCache;
                    if (_alternateMemoryCache.TryGetValue(region, out regionCache))
                    {
                        if (!regionCache.ContainsKey(key))
                            regionCache.Add(key, value);
                        else
                            regionCache[key] = value;
                    }
                }
    
                internal static void Remove(string key, string region)
                {
                    Dictionary<string, object> regionCache;
                    if (_alternateMemoryCache.TryGetValue(region, out regionCache))
                    {
                        if (regionCache.ContainsKey(key))
                            regionCache.Remove(key);
                    }
                }
    
                private static bool IsRestrictedRegionName(string typeName)
                {
                    return _typeNameRegionRestrictions.Contains(typeName);
                }
            }
            #endregion
    
    
        }
    }
    
  • Published on
    I had this problem recently in Visual Studio that drove me mad! It was a VB ASP.NET web project and Intellisense would not work on ASPX pages, complaining about the asp tag prefix. There is a lot of documented bugs/fixes for this online (google it), including deleting the solution .suo file, clearing out bin/obj files, deleting the visual studio reflected schemas files (under the app data folder), clearing your VS settings. I tried them all but to no avail.. My problem though, was quite different in 2 ways.. Firstly my project was building and running absolutely fine (not sure about this for the other people's problems, but maybe worth noting). Also, in my opinion, the cause of my problem was the way I had set up the project to re-use an existing web projects files and code (I was re-using quite a lot of code files from another project by adding them as linked files for the code-infront and a DLL reference for the code behind.) I have had some problems with VB project in the past due to this kind of thing, because VB does not define the root namespace in the code files it has caused some issues, which led me to believe the problem was being caused by the vbproj settings. I remembered that by default I have option strict set to "on" for VB projects, since the project was building but the designer was just being "whingy" I decided to turn option strict off... It worked! :)
  • Published on
    Often applications allow a user to specify inputs by providing the IDs, or unique names of items which can be found in the database. Using the user provided collection of items, you would query your data and hopefully return a collection with the same number of elements as what the user was searching for. In some cases though, not all the items the user provided will be found in the database. I recently wrote a generic helper method which provides warnings to the user for any "missing" elements (i.e. they asked for it in the source but it wasn't in the output).
    
    public static class MissingItemsHelper
        {
            /// <summary>
            /// Will display a message to the user showing any items that existing in the itemsToFind collection that did not exist in the collectionToSearch (using the Equals operator)
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="itemsToFind">The collection containing the items which need to be checked against the other list</param>
            /// <param name="collectionToSearch">The collection which will be checked for the existance of each item</param>
            /// <param name="missingItemMessageTextSelector">For items that are missing, this selector function should return the text you want to output in the message for each item</param>
            /// <param name="messageNounText">The singular noun which identifies what you are currently searching</param>
            public static string GetWarningsIfItemsNotInCollection<T>(
                IEnumerable<T> itemsToFind,
                IEnumerable<T> collectionToSearch,
                Func<T, string> missingItemMessageTextSelector,
                string messageNounText)
            {
                //any missing items? - find those which dont have an equal in the target list
                IEnumerable<T> missingItems =
                    (from sourceItem in itemsToFind
                     where collectionToSearch.Any((f) => f.Equals(sourceItem)) == false
                     select sourceItem);
    
                //if there were some missing items, show the message to the user with the missing items text
                if (missingItems.Count() > 0)
                        return string.Format("The following {0}s were not found:\r\n", messageNounText)
                                        + string.Join("\r\n",missingItems.Select(missingItemMessageTextSelector).ToArray());
    
                return string.Empty;
            }
        }
    
    I've tried to keep it as generic as possible, which is why you must provide the type T of the elements and a function which selects the "missing" information as well as a noun which describes that information. For example:
    
    MissingItemsHelper.GetWarningsIfItemsNotInCollection<long>(
                        inputIds, (from d in dataItems select d.UniqueId),
                        new Func<long, string>((id) => id.ToString()), "Unique ID");
    
    This could be extended further to take various types with a comparison operator, but for simplicity I have kept to one type.
  • Published on
    Using Silverlight and MVVM you often use property change tracking mechanisms, such as implementing INotifyPropertyChanged and using ObservableCollections (which implement INotifyCollectionChanged). This is fine when you are only interested in letting the UI synchronise with your data in the ViewModel (and vice-versa) but sometimes you need to track these changes in the code, either within your own class or in another class elsewhere. I had this issue recently, where I needed to know in my "Results" ViewModel when anything changed in any of my various "Input" ViewModels so that I could invalidate the results (so the user knows they need to re-calculate). In order to achieve this I needed to listen to events in the following 3 categories on many properties:
    • Property changed (setter called)
    • Collection changed (items added/removed)
    • Collection item property changed (element of a list has a property changed)
    Rather than having to write event handling code and logic everywhere, I decided to design a base class that my "Input" viewmodels can inherit from that would take care of rolling up these 3 scenarios into a single event. In my "Results" class I then can simply add a listener for the one "InputsChanged" event. My view model base derives from a base implementing INotifyPropertyChanged and looks as follows:
    
    public abstract class ResultsInputViewModelBase : ViewModelBase
        {
            /// <summary>
            /// A list of tracked properties that implement INotifyCollectionChanged, therefore need the CollectionChanged tracking
            /// </summary>
            private Dictionary<string, PropertyInfo> _collectionChangingPropertiesToTrack = new Dictionary<string, PropertyInfo>();
    
            /// <summary>
            /// A list of tracked properties that implement IEnumerable, therefore may need the items tracking
            /// </summary>
            private Dictionary<string, PropertyInfo> _enumerablePropertiesToTrack = new Dictionary<string, PropertyInfo>();
    
            /// <summary>
            /// Initializes a new instance of the <see cref="ResultsInputViewModelBase" /> class. In the base constructor we setup the auto-tracking feature, which attaches to PropertyChangedEvent and prepares for tracking CollectionChanged and sub-items PropertyChanged events
            /// </summary>
            public ResultsInputViewModelBase()
            {
                // subscribe the property changed event for this instance
                this.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(this.ResultsInputViewModelBase_PropertyChanged);
    
                // look for properties that implement INotifyCollectionChanged (observable collections) in the tracked properties so we can auto-track these aswel
                foreach (string propertyName in this.TrackedInputProperties)
                {
                    object currentValue = this;
    
                    // find the property info using reflection
                    if (!string.IsNullOrWhiteSpace(propertyName))
                    {
                        PropertyInfo pi = null;
    
                        // nested property?
                        if (propertyName.Contains("."))
                        {
                            // child property - iterate the tree
                            Type currentType = this.GetType();
    
                            string[] props = propertyName.Split('.');
                            int pc = 0;
                            foreach (string p in props)
                            {
                                pc++;
                                pi = currentType.GetProperty(p);
                                if (pi != null && pc < props.Length)
                                {
                                    currentType = pi.PropertyType;
                                    currentValue = pi.GetValue(currentValue, null);
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }
                        else
                        {
                            // direct property
                            pi = this.GetType().GetProperty(propertyName);
                        }
    
                        if (pi != null)
                        {
                            // does this property implement INotifyCollectionChanged?
                            if (typeof(INotifyCollectionChanged).IsAssignableFrom(pi.PropertyType))
                            {
                                // add the PropertyInfo to the list of tracked collections, so we can attach when the value != null
                                this._collectionChangingPropertiesToTrack.Add(propertyName, pi);
    
                                // incase its already != null, we can attempt to attach now
                                this.TryAttachCollectionTracker(pi, currentValue);
                            }
    
                            // does this property implement IEnumerable?
                            if (typeof(IEnumerable).IsAssignableFrom(pi.PropertyType))
                            {
                                // add the PropertyInfo to the list of tracked collections, so we can attach when the value != null
                                this._enumerablePropertiesToTrack.Add(propertyName, pi);
    
                                // incase its already != null, we can attempt to attach now
                                this.TryAttachEnumeratedPropertyChangeTracker(pi, currentValue);
                            }
                        }
                    }
                }
            }
    
            /// <summary>
            /// Event is fired whenever a tracked property or collection is changed in the derived class
            /// </summary>
            public event EventHandler InputsChanged;
    
            /// <summary>
            /// Gets the properties that are tracked in this base class. Implement in a derived class to signal each property which needs to raise the InputsChanged event
            /// </summary>
            protected abstract string[] TrackedInputProperties
            {
                get;
            }
    
            /// <summary>
            /// Provides a way for derived classes to inform that something in their inputs that requires a re-calculation has changed,
            /// although they shouldn't need to call this manually - put the property name in the TrackedInputProperties instead
            /// </summary>
            protected void OnInputsChanged()
            {
                if (this.InputsChanged != null)
                {
                    this.InputsChanged(this, EventArgs.Empty);
                }
            }
    
            /// <summary>
            /// Attempts to get the value of a property that implements INotifyCollectionChanged, if the value is non-null, attaches to the CollectionChanged event
            /// </summary>
            /// <param name="pi">Property Info instance of the target property</param>
            /// <param name="container">The object containing the collection property</param>
            private void TryAttachCollectionTracker(PropertyInfo pi, object container)
            {
                // read the value of the property for the current instance
                INotifyCollectionChanged collection_propValue = pi.GetValue(container, null) as INotifyCollectionChanged;
    
                // if the property has a value, we can attach to its CollectionChanged event
                if (collection_propValue != null)
                {
                    collection_propValue.CollectionChanged += new NotifyCollectionChangedEventHandler(this.ResultsInputViewModelBase_CollectionChanged);
                }
            }
    
            /// <summary>
            /// Attempts to get the value of a property that implements IEnumerable, if the value is non-null, attaches to the child elements PropertyChanged event (if implemented)
            /// </summary>
            /// <param name="pi">Property Info instance of the target property</param>
            /// <param name="container">The object containing the enumerable property</param>
            private void TryAttachEnumeratedPropertyChangeTracker(PropertyInfo pi, object container)
            {
                // read the value of the property for the current instance
                IEnumerable collection_propValue = pi.GetValue(container, null) as IEnumerable;
    
                // if the property has a value, we can attach to its CollectionChanged event
                if (collection_propValue != null)
                {
                    foreach (var element in collection_propValue)
                    {
                        if (element is ResultsInputViewModelBase)
                        {
                            ((ResultsInputViewModelBase)element).InputsChanged += this.InputsChanged;
                        }
                        else if (element is INotifyPropertyChanged)
                        {
                            ((INotifyPropertyChanged)element).PropertyChanged += new PropertyChangedEventHandler(this.ResultsInputViewModelBase_TrackedElementPropertyChanged);
                        }
                    }
                }
            }
    
            /// <summary>
            /// Fires when any property that raises PropertyChanged event is called in the derived class
            /// </summary>
            /// <param name="sender">Object raising the event</param>
            /// <param name="e">Event arguments</param>
            private void ResultsInputViewModelBase_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
            {
                // if the property that has raised the event is one of our tracked properties, we can apply further processing logic
                if (Array.IndexOf(this.TrackedInputProperties, e.PropertyName) >= 0)
                {
                    object currentValue = this;
    
                    // find the property info using reflection
                    if (!string.IsNullOrWhiteSpace(e.PropertyName))
                    {
                        PropertyInfo pi = null;
    
                        // nested property?
                        if (e.PropertyName.Contains("."))
                        {
                            // child property - iterate the tree
                            Type currentType = this.GetType();
    
                            string[] props = e.PropertyName.Split('.');
                            int pc = 0;
                            foreach (string p in props)
                            {
                                pc++;
                                pi = currentType.GetProperty(p);
                                if (pi != null && pc < props.Length)
                                {
                                    currentType = pi.PropertyType;
                                    currentValue = pi.GetValue(currentValue, null);
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }
                    }
    
                    // if the value of a changeable collection has just been set, we need to (re-)attach our collection tracker
                    if (this._collectionChangingPropertiesToTrack.ContainsKey(e.PropertyName))
                    {
                        this.TryAttachCollectionTracker(this._collectionChangingPropertiesToTrack[e.PropertyName], currentValue);
                    }
    
                    // if the value of a enumerable has just been set, we need to (re-)attach our collection tracker
                    if (this._enumerablePropertiesToTrack.ContainsKey(e.PropertyName))
                    {
                        this.TryAttachEnumeratedPropertyChangeTracker(this._enumerablePropertiesToTrack[e.PropertyName], currentValue);
                    }
    
                    this.OnInputsChanged();
                }
            }
    
            /// <summary>
            /// Fires when any property of an element of a collection that is being tracked is fired
            /// </summary>
            /// <param name="sender">Object raising the event</param>
            /// <param name="e">Event arguments</param>
            private void ResultsInputViewModelBase_TrackedElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
            {
                this.OnInputsChanged();
            }
    
            /// <summary>
            /// Fires when a collection of a tracked property changes
            /// </summary>
            /// <param name="sender">Object raising the event</param>
            /// <param name="e">Event arguments</param>
            private void ResultsInputViewModelBase_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
            {
                // we need to attach the property changed etc of the new items
                if (e.NewItems != null)
                {
                    foreach (var element in e.NewItems)
                    {
                        if (element is ResultsInputViewModelBase)
                        {
                            ((ResultsInputViewModelBase)element).InputsChanged += this.InputsChanged;
                        }
                        else if (element is INotifyPropertyChanged)
                        {
                            ((INotifyPropertyChanged)element).PropertyChanged += new PropertyChangedEventHandler(this.ResultsInputViewModelBase_TrackedElementPropertyChanged);
                        }
                    }
                }
    
                // we should stop tracking the items leaving the collection
                if (e.OldItems != null)
                {
                    foreach (var element in e.OldItems)
                    {
                        if (element is ResultsInputViewModelBase)
                        {
                            ((ResultsInputViewModelBase)element).InputsChanged -= this.InputsChanged;
                        }
                        else if (element is INotifyPropertyChanged)
                        {
                            ((INotifyPropertyChanged)element).PropertyChanged -= new PropertyChangedEventHandler(this.ResultsInputViewModelBase_TrackedElementPropertyChanged);
                        }
                    }
                }
    
                this.OnInputsChanged();
            }
        }
    
    This class essentially adds internal listeners to all the different kinds of events that the derived class may raise that we are interested in. It leaves one single property that must be implemented in the derived class, where the programmer can list the properties which should be tracked. For example:
    
    protected override string[] TrackedInputProperties
            {
                get { return new string[] {
                    "AgeBandFilters",
                    "MaritalStatusFilters"
                }; }
            }
    
    Finally, in the "Results" ViewModel, I pass in an instance of my derived class and then listen for the "InputsChanged" event:
    
    public ExampleInputViewModel ExampleInputViewModel
            {
                get { return _exampleInputViewModel; }
                set {
                    //track changes in input configs to invalidate results
                    RemoveInputChangedHandler(_exampleInputViewModel);
                    _exampleInputViewModel = value;
                    AddInputChangedHandler(_exampleInputViewModel);
    
                    RaisePropertyChanged("ExampleInputViewModel"); }
            }
    
     private void RemoveInputChangedHandler(ResultsInputViewModelBase inputConfigViewModel)
            {
                if(inputConfigViewModel != null)
                    inputConfigViewModel.InputsChanged -= new EventHandler(inputConfigViewModel_InputsChanged);
            }
    
            private void AddInputChangedHandler(ResultsInputViewModelBase inputConfigViewModel)
            {
                if (inputConfigViewModel != null)
                    inputConfigViewModel.InputsChanged += new EventHandler(inputConfigViewModel_InputsChanged);
            }
    
            void inputConfigViewModel_InputsChanged(object sender, EventArgs e)
            {
                    //invalidate results
                    CurrentResults = null;
            }
    
  • Published on
    In SQL Server Management Studio the default setting for Query Execution 'ARITHABORT' setting is ON. In ADO.NET the default setting is OFF. This can cause problems when trying to optimise your slow running queries, as the execution plans used by .NET and SSMS can be different. This can result in different execution times of your RPC completed vs SP completed in SQL Profiler. Also, it can cause your ADO.NET based queries to run slower, if the plan was optimised for the SSMS based query. In order to avoid this problem, I would recommend setting the option to OFF in SSMS: Tools > Options > Query Execution > SQL Server > Advanced.. Also, if you have come across this problem, after having changed the setting it may be worth clearing your plan cache:
    DBCC FREEPROCCACHE