Dan Rigsby - Coding Up Style

.Net, C#, & Wcf Development

Archive for the 'Common Libraries' Category


Remove Icon from WPF Window

Posted by Dan Rigsby on 26th May 2008

In general, a window should always have an icon because it helps give context to the window.  However, there are occasions when you may want a window with icon such as a custom tool window or some other dialog. In Windows Forms if you want a window without an icon, you could just simply set:
 
this.ShowIcon = false;
 
In WPF, there is no simple way to just remove the icon.  If you try to just set the Icon to null, it will display the default windows icon.  The only way to disable the icon is to use some interop code to remove the icon directly through the windows API:
 
using System;
using System.Windows;
using System.Windows.Interop;
using System.Runtime.InteropServices;

public partial class WindowWithoutIcon : Window
{
    [DllImport("user32.dll")]
    static extern int GetWindowLong(IntPtr hwnd, int index);

    [DllImport("user32.dll")]
    static extern int SetWindowLong(IntPtr hwnd, int index, int newStyle);

    [DllImport("user32.dll")]
    static extern bool SetWindowPos(IntPtr hwnd, IntPtr hwndInsertAfter, int x, int y, int width, int height, uint flags);

    [DllImport("user32.dll")]
    static extern IntPtr SendMessage(IntPtr hwnd, uint msg, IntPtr wParam, IntPtr lParam);

    const int GWL_EXSTYLE = -20;
    const int WS_EX_DLGMODALFRAME = 0×0001;
    const int SWP_NOSIZE = 0×0001;
    const int SWP_NOMOVE = 0×0002;
    const int SWP_NOZORDER = 0×0004;
    const int SWP_FRAMECHANGED = 0×0020;
    const uint WM_SETICON = 0×0080;

    public MainWindow()
    {
        InitializeComponent();
    }

    protected override void OnSourceInitialized(EventArgs e)
    {
        base.OnSourceInitialized(e);

        // Get this window’s handle
        IntPtr hwnd = new WindowInteropHelper(this).Handle;

        // Change the extended window style to not show a window icon
        int extendedStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
        SetWindowLong(hwnd, GWL_EXSTYLE, extendedStyle | WS_EX_DLGMODALFRAME);

        // Update the window’s non-client area to reflect the changes
        SetWindowPos(hwnd, IntPtr.Zero, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
    }
}
 
 

Posted in Common Libraries, WPF | 1 Comment »

How to grayout an image in .Net

Posted by Dan Rigsby on 28th March 2008

Here is a handy method for making a grayscale version of an image.  I use this method a lot to grayout icons that I wish to show as disabled.  All you need to do is pass in the image and it will apply a grayscale over it.  The key to getting all of this to work is the ColorMatrix.  There is a detailed article about how this works on codeproject: http://www.codeproject.com/KB/GDI-plus/colormatrix.aspx.

public static void ApplyGrayscale(
    ref Image image)
{
    // Build color matrix set at 1/3
    ColorMatrix matrix = new ColorMatrix();
    matrix[0, 0] = 1/3f;
    matrix[0, 1] = 1/3f;
    matrix[0, 2] = 1/3f;
    matrix[1, 0] = 1/3f;
    matrix[1, 1] = 1/3f;
    matrix[1, 2] = 1/3f;
    matrix[2, 0] = 1/3f;
    matrix[2, 1] = 1/3f;
    matrix[2, 2] = 1/3f;

    // Create image attributes that will applied to the image
    ImageAttributes attributes = new ImageAttributes();
    attributes.SetColorMatrix(matrix);

    Graphics g = null;
    try
    {
        // Get the graphics object from the image
        g = Graphics.FromImage(image);

        // Redraw the image on the graphics object using the grayscale color matrix
        g.DrawImage(image,
            new Rectangle(0, 0, image.Width, image.Height),
            0,
            0,
            image.Width,
            image.Height,
            GraphicsUnit.Pixel,
            attributes);
    }
    finally
    {
        if (g != null)
        {
            g.Dispose();
        }
    }
}

 

Here are some sample before and after images (of my daughter Claire):

claire clairegray

 

Here is another example with a more typical line-of-business image:

disk_blue disk_bluegray

 

To make this easier to try out or use, I have wrapped the method into a executable as well.  You can download the source for this here: http://www.danrigsby.com/Files/Rigsby.ImageUtilities.Grayscale.zip

To run the program, compile the code and execute the exe file while passing in the source file name and the file name you want to save the new grayscaled image to, like this:

Rigsby.ImageUtilities.Grayscale.exe "c:\Claire.jpg" "c:\Claire-Gray.jpg"
 

Posted in .Net, Common Libraries | 9 Comments »

Disposable Base Class

Posted by Dan Rigsby on 15th March 2008

trashcanMany classes are built that implement System.IDisposable, which is a good thing.  This pattern makes for a good design to clean up your objects and can be used by the using statement to easily dispose of your objects.  This article already assumes that you know the basics of the Dispose Pattern. However sometimes having just a Dispose() method isn’t always enough.  Many times you a combination of a Disposed event, a void Dispose(bool disposing) method for use by a deconstructor, a boolean flag to check if the object IsDisposed, and maybe a method to check if the object is disposed that can throw an exception.  Some "best practices" often dictate that you should be using some of these additional things.  You may be writing this logic over and over again for each class, or you might start with a basic IDisposable pattern and weeks later you decide to refactor it to add in something like the boolean flag for IsDisposed.

After facing these same issues for awhile, I decided to put together a simple Diposable base class with all of the recommended patterns for using Disposable.  Of course, this can’t always be used since you might already have a base class.  But many times a class will derive from IDisposable and nothing else.  This is just screaming for a Disposable base class that encapsulates this logic!  For classes that already have a base class, I also have a code snippet to include everything that’s in the base class.

Here are the features of the Disposable Base Class and Code Snippet:

  1. void Dispose() Method - This is just the standard Dispose method that is defined in the IDisposable interface.
  2. void Dispose(bool disposing) Method - This method is called from the Dispose() method passing in true.  Its called from the deconstructor using false.  This is the method that you should override in your parent class and check if disposing is true before disposing of managed code.  The reason for this is that the deconstructor would have already disposed of the managed code, so you shouldn’t try to do it again.  If the deconstrutor called this method, you should only dispose of unmanaged code.
  3. void CheckDisposed() Method - This method is marked protected and is used by the parent class to check if the object is disposed.  It will throw an ObjectDisposedException if necessary.
  4. bool IsDisposed Property - A simple property to check whether or not this object has been disposed yet.
  5. Disposed Event - This event is fired when the object has been disposed.

To use the base class, you just override the Dispose(bool disposing) method. An example of this base class in use could look like this:

public class MyClass : Disposable
{
    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            // Dispose any managed code here
        }

        // Dispose any unmanaged code here

        base.Dispose(disposing);
    }
}

 

Here is the base class:

using System;
using System.ComponentModel;

namespace Rigsby
{
    /// <summary>
    /// Represents a basic disposable class.
    /// </summary>
    public abstract class Disposable : IDisposable
    {
        #region Private Properties
        private bool m_IsDisposed = false;
        #endregion Private Properties

        #region Public Properties
        /// <summary>
        /// Gets a value indicating whether this instance is disposed.
        /// </summary>
        /// <value>
        ///     <c>true</c> if this instance is disposed; otherwise, <c>false</c>.
        /// </value>
        [Browsable(false)]
        public bool IsDisposed
        {
            get
            {
                return m_IsDisposed;
            }
        }
        #endregion Public Properties

        #region Constructors
        /// <summary>
        /// Initializes a new instance of the <see cref="Disposable"/> class.
        /// </summary>
        public Disposable()
        {
        }

        /// <summary>
        /// Releases unmanaged resources and performs other cleanup operations before the
        /// <see cref="Disposable"/> is reclaimed by garbage collection.
        /// </summary>
        ~Disposable()
        {
            Dispose(false);
        }
        #endregion Constructors

        #region IDisposable Members
        private event System.EventHandler m_Disposed;

        /// <summary>
        /// Occurs when this instance is disposed.
        /// </summary>
        public event System.EventHandler Disposed
        {
            add
            {
                m_Disposed += value;
            }
            remove
            {
                m_Disposed -= value;
            }
        }

        /// <summary>
        /// Releases unmanaged and - optionally - managed resources
        /// </summary>
        public void Dispose()
        {
            if (!m_IsDisposed)
            {
                this.Dispose(true);
                GC.SuppressFinalize(this);
            }
        }

        /// <summary>
        /// Releases unmanaged and - optionally - managed resources
        /// </summary>
        /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
        protected virtual void Dispose(bool disposing)
        {
            try
            {
                if (disposing)
                {
                    EventHandler handler = m_Disposed;
                    if (handler != null)
                    {
                        handler(this, EventArgs.Empty);
                        handler = null;
                    }
                }
            }
            finally
            {
                m_IsDisposed = true;
            }
        }
        #endregion IDisposable Members

        /// <summary>
        ///    <para>
        ///        Checks if the instance has been disposed of, and if it has, throws an <see cref="ObjectDisposedException"/>; otherwise, does nothing.
        ///    </para>
        /// </summary>
        /// <exception cref="ObjectDisposedException">
        ///    The instance has been disposed of.
        ///    </exception>
        ///    <remarks>
        ///    <para>
        ///        Derived classes should call this method at the start of all methods and properties that should not be accessed after a call to <see cref="Dispose()"/>.
        ///    </para>
        /// </remarks>
        protected void CheckDisposed()
        {
            if (m_IsDisposed)
            {
                string typeName = GetType().FullName;

                // TODO: You might want to move the message string into a resource file
                throw new ObjectDisposedException(
                    typeName,
                    String.Format(System.Globalization.CultureInfo.InvariantCulture,
                        "Cannot access a disposed {0}.",
                        typeName));
            }
        }
    }
}

Here is the code snippet version, or download it here.  If you use the snippet, you will want to manually change your class to derive from the IDisposable interface, then add this snippet.

<?xml version="1.0" encoding="utf-8"?> <CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">   <CodeSnippet Format="1.0.0">     <Header>       <Title>IDisposable</Title>       <Shortcut>       </Shortcut>       <Description>Implements the IDisposable interface with additional best practices.</Description>       <Author>Dan Rigsby</Author>     </Header>     <Snippet>       <Code Language="csharp"><![CDATA[        #region IDisposable Members
        private bool m_IsDisposed = false;
        private event System.EventHandler m_Disposed;

        /// <summary>
        /// Gets a value indicating whether this instance is disposed.
        /// </summary>
        /// <value>
        ///     <c>true</c> if this instance is disposed; otherwise, <c>false</c>.
        /// </value>
        [System.ComponentModel.Browsable(false)]
        public bool IsDisposed
        {
            get
            {
                return m_IsDisposed;
            }
        }

        /// <summary>
        /// Occurs when this instance is disposed.
        /// </summary>
        public event System.EventHandler Disposed
        {
            add
            {
                m_Disposed += value;
            }
            remove
            {
                m_Disposed -= value;
            }
        }

        /// <summary>
        /// Releases unmanaged and - optionally - managed resources
        /// </summary>
        public void Dispose()
        {
            if (!m_IsDisposed)
            {
                this.Dispose(true);
                System.GC.SuppressFinalize(this);
            }
        }

        /// <summary>
        /// Releases unmanaged and - optionally - managed resources
        /// </summary>
        /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
        protected virtual void Dispose(bool disposing)
        {
            try
            {
                if (disposing)
                {
                    System.EventHandler handler = m_Disposed;
                    if (handler != null)
                    {
                        handler(this, System.EventArgs.Empty);
                        handler = null;
                    }
                }
            }
            finally
            {
                m_IsDisposed = true;
            }
        }

        /// <summary>
        ///    <para>
        ///        Checks if the instance has been disposed of, and if it has, throws an <see cref="ObjectDisposedException"/>; otherwise, does nothing.
        ///    </para>
        /// </summary>
        /// <exception cref="System.ObjectDisposedException">
        ///    The instance has been disposed of.
        ///    </exception>
        ///    <remarks>
        ///    <para>
        ///        Derived classes should call this method at the start of all methods and properties that should not be accessed after a call to <see cref="Dispose()"/>.
        ///    </para>
        /// </remarks>
        protected void CheckDisposed()
        {
            if (m_IsDisposed)
            {
                string typeName = GetType().FullName;

                // TODO: You might want to move the message string into a resource file
                throw new System.ObjectDisposedException(
                    typeName,
                    String.Format(System.Globalization.CultureInfo.InvariantCulture,
                        "Cannot access a disposed {0}.",
                        typeName));
            }
        }
        #endregion IDisposable Members]]></Code>     </Snippet>   </CodeSnippet> </CodeSnippets>

kick it on DotNetKicks.com

Posted in .Net, Common Libraries | 1 Comment »

Generic Notify Property Change Controller

Posted by Dan Rigsby on 14th March 2008

This is another example of a class you could put into a common library.   Suppose I want to create a class that fires an event every time the value of a property changes.  I could implement such a class like this:

public class MyClass : INotifyPropertyChanged
{
    private string m_Text;
    public string Text
    {
        get { return m_Text; }
        set
        {
            if (m_Text != value)
            {
                m_Text = value;
                OnPropertyChanged(“Text”);
            }
        }
    }

    protected virtual void OnPropertyChanged(
        string propertyName)
    {
        PropertyChangedEventHandler handler = m_PropertyChanged;
        if (handler != null)
        {
            m_PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    #region INotifyPropertyChanged Members
    private event PropertyChangedEventHandler m_PropertyChanged;
    public event PropertyChangedEventHandler PropertyChanged
    {
        add { m_PropertyChanged += value; }
        remove { m_PropertyChanged -= value; }
    }
    #endregion INotifyPropertyChanged Members
}
 
If you have a large class library and a lot of properties, this can add up to a lot of code.  There is an easier way to do this at a very small cost of performance.  Ill show the code for the PropertyController class at the end of this post, but this is an example of what the above code could look like:
 
public class MyClass : INotifyPropertyChanged
{
    private PropertyController m_PropertyController
    private string m_Text;
    public string Text
    {
        get { return m_Text; }
        set { m_PropertyController.ChangeProperty(“Text”, value);
    }

    #region INotifyPropertyChanged Members
    public event PropertyChangedEventHandler PropertyChanged
    {
        add { m_PropertyController.PropertyChanged += value; }
        remove { m_PropertyController.PropertyChanged -= value; }
    }
    #endregion INotifyPropertyChanged Members
}

 

That is significantly less code and much cleaner.  Just, imagine if I had a class library with 30 classes.

You could also do this:

set { m_PropertyController.ChangeProperty(“Text”, value);

 

instead of:

set { m_PropertyController.ChangeProperty(value);

 

The cost of doing this is that the PropertyController has to look at the stack trace, but depending on what you are doing, this may be worth the cost.

The ChangeProperty method returns a boolean to indicate whether or not the value was changed.  So inside your property code you could react depending on the result.

Here is the complete PropertyController class.  Feel free to use it, modify it, ignore it, etc. You could even use this class and not even expose the PropertyChanged event, if you don’t need it.

public class PropertyController : INotifyPropertyChanged, IDisposable
{
    private Dictionary<string, PropertyInfo> m_Properties =
        new Dictionary<string, PropertyInfo>();

    public PropertyController()
    {
    }

    #region INotifyPropertyChanged Members
    private event PropertyChangedEventHandler m_PropertyChanged;

    public event PropertyChangedEventHandler PropertyChanged
    {
        add
        {
            m_PropertyChanged += value;
        }
        remove
        {
            m_PropertyChanged -= value;
        }
    }
    #endregion INotifyPropertyChanged Members

    protected PropertyInfo GetProperty(string propertyName)
    {
        if (!m_Properties.ContainsKey(propertyName))
        {
            m_Properties.Add(propertyName, this.GetType().GetProperty(propertyName));
        }

        return m_Properties[propertyName];
    }

    public virtual bool ChangeProperty(object newValue)
    {
        return ChangeProperty(new System.Diagnostics.StackTrace().GetFrame(1).GetMethod().Name, newValue);
    }

    public virtual bool ChangeProperty(string propertyName, object newValue)
    {
        System.Reflection.PropertyInfo property =
            GetProperty(propertyName);

        if (property.GetValue(this, null) != newValue)
        {
            property.SetValue(this, newValue, null);
            OnPropertyChanged(propertyName);

            return true;
        }

        return false;
    }

    public virtual void OnPropertyChanged(
        string propertyName)
    {
        PropertyChangedEventHandler handler = m_PropertyChanged;
        if (handler != null)
        {
            m_PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    #region IDisposable Members
    public void Dispose()
    {
        m_PropertyChanged = null;
    }
    #endregion IDisposable Members
}

Posted in .Net, Common Libraries | 2 Comments »

How to Extend the Provider Model to Make It Easy to Use

Posted by Dan Rigsby on 22nd February 2008

The Provider Model has been around for quite awhile now and its in use all over the .Net Framework and Enterprise Library since .Net 2.0.  The provider model allows you to program against an intermediary, while the actual implementation can be defined in the app.config file.  The best example of this is a data access layer.  You might program a generic data access layer, but the actual implementation may be for Sql Server or Oracle and can be decided in the app.config file.  I have used the provider model to abstract things such as a data access layer, a geocoding service, an authentication system, etc.  Its nice to be able to just create a different implementation and swap it out in the app.config filer.

There is a decent amount of information out there (including a recent post by Joel Ross) and there is built in support for it in System.Configuration.Provider.  However, while the tools in .Net make it possible to use the Provider Model, there is little guidance and some missing features in this namespace. This article is about how to extend the provider model to make it easier to use, and give a little insight into how it might be used.  We are going to specifically look at the following areas:

  1. ProviderBase extensions:
    1. Exposing the configuration values through the provider so they can be used later in the code
    2. Using the provider type as the default name if no name is specified
  2. How to create a ProvidersSection that allows you to specify the default provider to use
  3. ProviderCollection extensions:
    1. Add Generics support
    2. Add the ability to get an Provider by index instead of just by name
  4. How to build a generic ProviderRepository

Note: At the bottom of this post I have zipped up all of the code and samples in this article.  The sample included is a complete working example of the basic principles outlined here.

Definitions

Abstract Provider: an abstract class that services as a base for your providers.  This usually contains all abstract methods and properties or overloaded methods and implementation details that can be shared by all providers.  This usually derives from ProviderBase.

Provider:  the actual implementation of an abstract base provider.  For instance, this could be your actual SQL Server implementation of the abstract data provider.

ProvidersSection: the configuration section used by providers in the app.config file

ProviderCollection: a collection of providers

ProviderRepository: a repository that abstracts the need to manually try to determine which provider to use from the app.config file and wraps up tools needed to work with provider and the entire collection of providers.

ProviderBase Extensions

When working with the provider model each provider is named.  This is important so that each provider in the list can be recognized from the others such as:

<DataService defaultProvider="SqlDataProvider">
    <providers>
        <add
            name="SqlDataProvider"
            type="DataAccessLayer.SqlClient.SqlDataProvider, DataAccessLayer.SqlClient"
        />
        <add
            name="OracleDataProvider"
            type="DataAccessLayer.OleDb.OracleDataProvider, DataAccessLayer.OleDb"
        />
    </providers>
</DataService>

 

As you can see, each provider has a name and a type.  Here is my extended implementation of ProviderBase:

using System;
using System.Collections.Specialized;
using System.Configuration;
using System.Configuration.Provider;

namespace Rigsby.Configuration.Provider
{
    /// <summary>
    /// Provides a base implementation for the extensible provider model.
    /// </summary>
    public class ProviderBase : System.Configuration.Provider.ProviderBase
    {
        #region Private Properties
        private NameValueCollection m_Configuration = new NameValueCollection();
        private bool m_IsInitialized = false;
        private string m_Name = String.Empty;
        #endregion Private Properties

        #region Public Properties
        /// <summary>
        /// Gets the configuration.
        /// </summary>
        /// <value>The configuration.</value>
        public NameValueCollection Configuration
        {
            get
            {
                return m_Configuration;
            }
        }

        /// <summary>
        /// Gets or sets the friendly name used to refer to the provider during configuration.
        /// </summary>
        /// <value></value>
        /// <returns>The friendly name used to refer to the provider during configuration.</returns>
        public new string Name
        {
            get
            {
                return m_Name;
            }
            set
            {
                m_Name = value;
            }
        }

        /// <summary>
        /// Gets a value indicating whether this instance is initialized.
        /// </summary>
        /// <value>
        ///     <c>true</c> if this instance is initialized; otherwise, <c>false</c>.
        /// </value>
        public bool IsInitialized
        {
            get
            {
                return m_IsInitialized;
            }
        }
        #endregion Public Properties

        #region Overrides
        /// <summary>
        /// Initializes the provider.
        /// </summary>
        public void Initialize()
        {
            Initialize(String.Empty);
        }

        /// <summary>
        /// Initializes the provider.
        /// </summary>
        /// <param name="name">The friendly name of the provider.</param>
        public void Initialize(
            string name)
        {
            Initialize(name, new NameValueCollection());
        }

        /// <summary>
        /// Initializes the provider.
        /// </summary>
        /// <param name="name">The friendly name of the provider.</param>
        /// <param name="config">A collection of the name/value pairs representing the provider-specific attributes specified in the configuration for this provider.</param>
        public override void Initialize(
            string name,
            NameValueCollection config)
        {
            if (config == null)
            {
                config = new NameValueCollection();
            }

            // Get default name if empty or null
            if (String.IsNullOrEmpty(name))
            {
                if (!String.IsNullOrEmpty(m_Name))
                {
                    name = m_Name;
                }
                else
                {
                    name = this.GetType().Name;
                }
            }
            m_Name = name;

            // Store configuration values
            m_Configuration.Clear();
            foreach (string key in config.Keys)
            {
                m_Configuration.Add(key, config[key]);
            }

            // Call the base class’s Initialize method
            base.Initialize(name, config);

            m_IsInitialized = true;
        }
        #endregion Overrides
    }
}

The default System.Configuration.Provider.ProviderBase will hide all of the configuration values after Initialize is called.  I wanted to expose this collection so that you can add in custom configuration attributes easily and access them later in your code.  The default provider base would also throw exceptions if there were any unknown attributes.  I found this to be undesirable. If I wanted to add a new attribute that only one of my providers might need, I would want to be able to add it without it on the fly without having to extend my provider and make sure it understood the attribute.  So now based on this new ProviderBase we can do things like this:

// Configuration file
<DataService defaultProvider="SqlDataProvider">
    <providers>
        <add
            name="SqlDataProvider"
            type="DataAccessLayer.SqlClient.SqlDataProvider, DataAccessLayer.SqlClient"
            useStoredProcedure="true"
        />
    </providers>
</DataService>

// Code
if (provider.Configuration["useStoredProcedure"])
{
    // handle stored procedures
}

 

This may not seem like much, but it can be a real time saver if you use the Provider Model a lot and need inject custom attributes.

Creating a ProvidersSection

In our previous example, we showed the list of providers an app.config file and the root configuration section specified a "defaultProvider" attribute.  This is an example of the custom ProvidersSection.  It’s just a generic ConfigurationSection that allows for a "defaultProvider" attribute and a collection of ProviderSettings.  You can extend this to add your own attributes, but for most purposes any custom attributes you will need will be on the provider settings themselves and not on the ProvidersSection.

using System;
using System.Configuration;

namespace Rigsby.Configuration.Provider
{
    /// <summary>
    /// A configuration section for a collection of providers.
    /// </summary>
    public class ProvidersSection : ConfigurationSection
    {
        private const string m_DefaultProviderProperty = "defaultProvider";

        /// <summary>
        /// Gets the providers.
        /// </summary>
        /// <value>The providers.</value>
        [ConfigurationProperty("providers")]
        public ProviderSettingsCollection Providers
        {
            get
            {
                return (ProviderSettingsCollection)base["providers"];
            }
        }

        /// <summary>
        /// Gets or sets the default provider.
        /// </summary>
        /// <value>The default provider.</value>
        [ConfigurationProperty(m_DefaultProviderProperty, IsRequired=false)]
        public string DefaultProvider
        {
            get
            {
                return (string)base[m_DefaultProviderProperty];
            }
            set
            {
                base[m_DefaultProviderProperty] = value;
            }
        }
    }
}

ProviderCollection Extensions

The default ProviderCollection does not contain support for generics.  This means you have to do a lot of extra casting and things aren’t strongly typed.  It is also setup to only allow retrieval of providers by name.   In some cases you need to be able to get the provider by index.  Suppose you want to setup the provider model to try to use the first provider in the list, and if that doesn’t work, then use the next provider, and so on.  If you could only get the providers by name, there is no way to easily get the next provider.  The custom ProviderCollection shown below adds generics support and the ability to retrieve a provider by index.

using System;
using System.Configuration;
using System.Configuration.Provider;

namespace Rigsby.Configuration.Provider
{
    /// <summary>
    /// Represents a collection of provider objects that inherit from <see cref="ProviderBase"/>.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class ProviderCollection<T> : ProviderCollection
        where T : Rigsby.Configuration.Provider.ProviderBase
    {
        #region Public Properties
        /// <summary>
        /// Gets the <see cref="T:DataProvider"/> with the specified name.
        /// </summary>
        /// <value></value>
        public new T this[string name]
        {
            get
            {
                return (T)base[name];
            }
        }

        /// <summary>
        /// Gets the cref="&lt;T&gt;"/> at the specified index.
        /// </summary>
        /// <value></value>
        public T this[int index]
        {
            get
            {
                int counter = 0;

                foreach(T provider in this)
                {
                    if (counter == index)
                    {
                        return provider;
                    }
                    counter++;
                }

                return null;
            }
        }
        #endregion Public Properties

        #region Public Methods
        /// <summary>
        /// Adds a provider to the collection.
        /// </summary>
        /// <param name="provider">The provider to be added.</param>
        /// <permissionSet class="System.Security.permissionSet" version="1">
        ///     <IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="UnmanagedCode, ControlEvidence"/>
        /// </permissionSet>
        public override void Add(
            System.Configuration.Provider.ProviderBase provider)
        {
            if (!(provider is T))
            {
                throw new ArgumentException(
                    String.Format("The provider is not of type {0}.", typeof(T).ToString()));
            }

            this.Add((T)provider);
        }

        /// <summary>
        /// Adds the specified provider.
        /// </summary>
        /// <param name="provider">The provider.</param>
        public void Add(
            T provider)
        {
            if (!provider.IsInitialized)
            {
                provider.Initialize();
            }

            base.Add(provider);
        }
        #endregion Public Methods
    }
}

Creating a Generic ProviderRepository

All of the changes listed above are extensions of the the default provider model to make it easier to use.  The ProviderRepository though is a new concept not in the default provider model, but builds on the extensions we have already talked about.  The ProviderRepository is designed to encapsulate the loading of providers from the app.config file.  It will contain the list of available providers and specify which provider should be used based on the "defaultProvider". It is a generic class that takes in the type of provider you are working with.  For most implementations you will probably be extending ProviderBase the, so you will use ProviderRepositoy<MyProviderType>.  For example if you have a custom data access layer provider you might call it DataProvider and use ProviderRepository<DataProvider>.

In the ProviderRepository you specify the name of the configuration section to use from the app.config file. If you leave this null or empty, then it will attempt to look for a configuration section with same name as the generic provider type.  So if you created it like ProviderRepository<Rigsby.Test.DataAccessLayer>, then it will look for a configuration section named <Rigsby.Test.DataAccessLayer> in the app.config file that is a ProvidersSection.

using System;
using System.Configuration;
using System.Configuration.Provider;
using System.Collections.Generic;
using System.Text;
using System.Web.Configuration;

namespace Rigsby.Configuration.Provider
{
    /// <summary>
    /// Represents a repository to give access to providers.
    /// </summary>
    public class ProviderRepository<T>
        where T : ProviderBase
    {
        #region Private Properties
        private T m_Provider = null;
        private ProviderCollection<T> m_Providers = null;
        private volatile object m_SyncRoot = new object();

        private string m_SectionName = String.Empty;
        #endregion Private Properties

        #region Public Properties
        /// <summary>
        /// Gets the provider.
        /// </summary>
        /// <value>The provider.</value>
        public T Provider
        {
            get
            {
                if (m_Provider == null && m_Providers.Count > 0)
                {
                    m_Provider = m_Providers[0];
                }

                return m_Provider;
            }
        }

        /// <summary>
        /// Gets the providers.
        /// </summary>
        /// <value>The providers.</value>
        public ProviderCollection<T> Providers
        {
            get
            {
                return m_Providers;
            }
        }

        /// <summary>
        /// Gets the name of the configuration section.
        /// </summary>
        /// <value>The name of the section.</value>
        public string SectionName
        {
            get
            {
                return m_SectionName;
            }
        }
        #endregion Public Properties

        #region Constructors
        /// <summary>
        /// Initializes a new instance of the <see cref="ProviderRepository&lt;T&gt;"/> class.
        /// </summary>
        public ProviderRepository(
            ) : this(true)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="ProviderRepository&lt;T&gt;"/> class.
        /// </summary>
        /// <param name="throwErrorIfUnableToLoadSection">if set to <c>true</c> [throw error if unable to load section].</param>
        public ProviderRepository(
            bool throwErrorIfUnableToLoadSection)
        {
            if (String.IsNullOrEmpty(m_SectionName))
            {
                m_SectionName = typeof(T).ToString();
            }

            LoadProviders(throwErrorIfUnableToLoadSection);
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="ProviderRepository&lt;T&gt;"/> class.
        /// </summary>
        /// <param name="sectionName">Name of the section.</param>
        public ProviderRepository(
            string sectionName) : this(sectionName, true)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="ProviderRepository&lt;T&gt;"/> class.
        /// </summary>
        /// <param name="sectionName">Name of the section.</param>
        /// <param name="throwErrorIfUnableToLoadSection">if set to <c>true</c> [throw error if unable to load section].</param>
        public ProviderRepository(
            string sectionName,
            bool throwErrorIfUnableToLoadSection)
        {
            m_SectionName = sectionName;
            LoadProviders(throwErrorIfUnableToLoadSection);
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="ProviderRepository&lt;T&gt;"/> class.
        /// </summary>
        /// <param name="provider">The provider.</param>
        public ProviderRepository(
            T provider)
        {
            m_Providers = new ProviderCollection<T>();
            m_Providers.Add(provider);

            m_Provider = provider;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="ProviderRepository&lt;T&gt;"/> class.
        /// </summary>
        /// <param name="providers">The providers.</param>
        public ProviderRepository(
            ProviderCollection<T> providers)
        {
            m_Providers = providers;
        }
        #endregion Constructors

        /// <summary>
        /// Loads the providers.
        /// </summary>
        protected virtual void LoadProviders(
            bool throwErrorIfUnableToLoadSection)
        {
            // Avoid claiming lock if providers are already loaded
            if (m_Providers == null)
            {
                lock (m_SyncRoot)
                {
                    // Do this again to make sure provider is still null
                    if (m_Providers == null)
                    {
                        // Get the providers
                        m_Providers = new ProviderCollection<T>();

                        // Get a reference to the section
                        ProvidersSection section = null;
                        try
                        {
                            section =
                                ConfigurationManager.GetSection(m_SectionName) as ProvidersSection;
                        }
                        catch (Exception)
                        {
                            section = null;
                        }

                        if (section == null)
                        {
                            if (throwErrorIfUnableToLoadSection)
                            {
                                throw new ProviderException(
                                    String.Format("Unable to load configuration section: ‘{0}’.",
                                        m_SectionName));
                            }
                        }
                        else
                        {
                            ProvidersHelper.InstantiateProviders(section.Providers, m_Providers, typeof(T));

                            if (m_Providers.Count > 0)
                            {
                                // If there is a default provider specified, then grab it, 
                                // else grab the first provider in the collection
                                if (!String.IsNullOrEmpty(section.DefaultProvider))
                                {
                                    m_Provider = (T)m_Providers[section.DefaultProvider];
                                }
                                else
                                {
                                    m_Provider = m_Providers[0];
                                }
                            }

                            if (throwErrorIfUnableToLoadSection)
                            {
                                // If we have no provider, then throw an exception
                                if (m_Provider == null)
                                {
                                    throw new ProviderException(
                                        String.Format("Unable to load default provider for section: ‘{0}’.",
                                            m_SectionName));
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

Putting It All Together

To get this all to work you just need to do the following:

  1. Create the base provider you want to use. This should derive from ProviderBase.
  2. Created at least one implementation of your base provider. This should derive from the class you made in the previous step.
  3. Setup a section in your app.config file to specify the providers.
  4. Create an instance of the ProviderRepository<> in your code that you will use to reference the provider.

Below are examples of these 4 steps to put all of this together.

Step 1 Example:

public abstract class DataProvider : ProviderBase
{
    public abstract System.Data.DataTable GetRows();

    public string GetConnectionString()
    {
        string connectionStringName = this.Configuration["connectionStringName"];
        if (String.IsNullOrEmpty(connectionStringName))
        {
            throw new ProviderException("Empty or missing connectionStringName");
        }
        if (WebConfigurationManager.ConnectionStrings[connectionStringName] == null)
        {
            throw new ProviderException("Missing connection string");
        }

        return WebConfigurationManager.ConnectionStrings
            [connectionStringName].ConnectionString;
    }
}

 

Step 2 Example:

public class SqlDataProvider : DataProvider
{
    // TODO: Implement data access layer here

    /// <summary>
    /// Gets the rows.
    /// </summary>
    /// <returns></returns>
    public override System.Data.DataTable GetRows()
    {
        return new System.Data.DataTable();
    }
}

 

Step 3 Example:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <section name="DataService"
            type="Rigsby.Configuration.Provider.ProvidersSection, Rigsby.Configuration.Provider"
            allowDefinition="MachineToApplication"
            restartOnExternalChanges="true" />
    </configSections>

    <connectionStrings>
        <add name="connectionString"
            providerName="System.Data.SqlClient"
            connectionString="Data Source=localhost;Initial Catalog=DB;UID=sa;PWD=;" />
    </connectionStrings>

    <DataService defaultProvider="SqlDataProvider">
        <providers>
            <add
                name="SqlDataProvider"
                type="Rigsby.Configuration.Provider.Sample.DataAccessLayer.SqlDataProvider,
                    Rigsby.Configuration.Provider.Sample"
                connectionStringName="connectionString"
                providerInvariantName="System.Data.SqlClient"
            />
        </providers>
    </DataService>
</configuration>
 

Step 4 Example:

public static class Program
{
    private static ProviderRepository<DataAccessLayer.DataProvider> m_DatabaseProviders =
        new ProviderRepository<DataAccessLayer.DataProvider>("DataService");

    public static void Main(string[] args)
    {
        Console.WriteLine(
            String.Format("ProviderName = ‘{0}’", m_DatabaseProviders.Provider.Name));
        Console.WriteLine(
            String.Format("ConnectionString = ‘{0}’", m_DatabaseProviders.Provider.GetConnectionString()));

        Console.ReadLine();
    }
}

 

Here is a link to the complete code and samples: http://www.danrigsby.com/files/rigsby.configuration.provider.zip

Posted in Common Libraries, Design Patterns | No Comments »

ReadOnlyController Codeproject Published

Posted by Dan Rigsby on 19th December 2007

I finally got around to publishing an article on codeproject.  I chose the ReadOnlyController as its a fairly simple concept, is an excellent demonstration of how to use the IExtenderProvider, and would be a small enough project to get up on codeproject and learn the ropes.  I have created projects on codeplex before.  Codeplex is very nice, but is meant for projects.  Single components like the ReadOnlyController are better suited for codeproject.

The ReadOnlyController is a Component so that can be dropped on a form in design mode and implements IExtenderProvider so that it can extend the properties on controls on the form. Controls that have either a Readonly or Enabled property can be extended to enable control from the ReadOnly Controller. See the screenshot below for how this might look in the designer:

ReadOnlyController

Link:
http://www.codeproject.com/KB/cs/ReadOnlyController.aspx

Posted in .Net, Common Libraries | No Comments »

Missing static generic alternatives in Enum class?

Posted by Dan Rigsby on 16th December 2007

I ran into an issue earlier this week while working with a generic class where one of the template parameters would represent a possible enum value.  (Basically we have different enum lists representing different actions). You cant use a “where” clause for the enum class.  So how would take a string or an int and cast it back to the type of enum defined in the template parameter? I had thought the static Enum class would provide new methods such as Enum.ToObject<T> and Enum.Parse<T> to match the non-generic methods, but they weren’t there.  My needs here were pretty specific, but I soon realized that every time I cast an into to an enum I had to cast the result of Enum.ToObject(int) to the enum type.  Why wouldn’t they have implemented generic methods for these common task?  Generics were built for stuff like this.

Here is a basic EnumUtilities class I built to work around this issue and to assist with enum casting in the future:

using System;
namespace ININ.Common
{
    /// <summary>   
    /// Utilities to assist with enums.   
    /// </summary>   
    public static class EnumUtilities
    {
        /// <summary>       
        /// Parses the enum.       
        /// </summary>       
        /// <typeparam name=”T”></typeparam>       
        /// <param name=”name”>The name.</param>       
        /// <returns></returns>       
        public static T ParseEnum<T>(
            string name)
        {
            if (String.IsNullOrEmpty(name))
            {
                throw new NullArguementException(“name is null or an empty string.”);
            }
            return (T)Enum.Parse(typeof(T), name);
        }        

        /// <summary>       
        /// Parses the enum ID to the enum type.       
        /// </summary>       
        /// <typeparam name=”T”></typeparam>       
        /// <param name=”i”>The i.</param>       
        /// <returns></returns>       
        public static T ToObject<T>(
            int i)
        {
            return (T)Enum.ToObject(typeof(T), i);
        }
    }
}

Posted in .Net, Common Libraries | No Comments »