Vishful thinking…

Using ‘params’ as a part of delegate definition !!!***???

Posted in Uncategorized by viswaug on September 19, 2007

Today I just got curious about how the .NET compiler will handle a delegate definition with a ‘params’ parameter that will let you specify a variable number of parameters on a method. I know it doesn’t make sense but that i was curious as to how the .NET compiler will react to it. After a quick test, the results were somewhat expected. Here are my observations

  • To my dislike, the .NET compiler did not complain about the following definition

delegate void TestDelegate(int value, params object[] others);

  • I was actually able to create an instance of the delegate for the method with the following definition

No Error here

TestDelegate ni = new TestDelegate(IntCompareValidate);

Method definition

        private void IntCompareValidate(int value, object other1)

        {

            //Do something

        }

  •  But the compiler did not let me create an instance of the delegate for the method with the following definition

Error here. ” No overload for ‘IntBetweenValidate’ matches delegate ‘MockProject1.TestDelegate’ “

TestDelegate ni = new TestDelegate(IntBetweenValidate);

Method definition

        private void IntBetweenValidate(int value, object other1, object other2)

        {

            //Do something

        }

Just thinking a little bit more about it, I was thinking maybe the following would have been better. But then again I also do think that the .NET compiler should throw an error on the delegate definition instead of reacting the way it is.

No error here.

TestDelegate n1 = new TestDelegate(IntBetweenValidate);

TestDelegate n2 = new TestDelegate(IntCompareValidate);

 

Error here.

TestDelegate n1 = new TestDelegate(IntBetweenValidate);

n1 += new TestDelegate(IntCompareValidate);

 

What I am trying to say is that there should not be an error as long as all the functions added to the delegate have a consistent signature and there should be an error when they are not. But it is definitely going to be hard for the compiler to implement the above. But then again if you can do the above, the purpose of the delegates are kind of defeated. But it is just a thought…

What do you guys think?

Using custom names for the ConfigurationElementCollection entries

Posted in Uncategorized by viswaug on September 19, 2007

I have been using the .NET configuration library pretty extensively and one thing about using the ConfigurationElementCollection kind of just kept bothering me. All of my custom sections implementing ConfigurationElementCollection always used “add” as the default element name for its entries. I wanted it to be named something more meaningful than “add” which did not make sense all the time. For example, I wanted to be able to use “entry” as the element name instead of “add” like shown below.

ConfigurationElementCollection

Nothing the documentation for the .NET configuration stood out to me that will let me use a more meaningful name. Using a different custom name for the element entries didn’t turn out to be hard to. It was just a matter of looking in the right places to figure how to get it done. This can be accomplished by decorating the property of the custom ConfigurationElementCollection type in the ConfigurationSection with the ConfigurationCollectionAttribute and specifying the “AddItemName” which is an optional parameter like shown below.

    public class TestSection: ConfigurationSection

    {

        public TestSection() { }

 

        [ConfigurationProperty(“NameValues”, IsDefaultCollection = true)]

        [ConfigurationCollection(typeof(NameValueElementCollection), AddItemName=“entry”)]

        public NameValueElementCollection NameValues

        {

            get { return (NameValueElementCollection)base[“NameValues”]; }

        }

    }

Check out the Yahoo MapMixer

Posted in Uncategorized by viswaug on September 18, 2007

I just recently came across the new MapMixer service from Yahoo! which lets you upload your own images and overlay them on top of Yahoo maps. The service lets you pick points on your image and the Yahoo! map to allow you to geo-reference the uploaded image. The generated map can be shared with others and/or embedded in websites and blogs. It is a real simple way of sharing map overlays. The opacity of these map overlays can be adjusted on the map which is pretty cool. The MapCruncher software from Microsoft is much more powerful by letting you generate map tiles that can be used as overlays over Microsoft VirtualEarth. The image tiles, which can get pretty huge, need to be hosted someplace to be used in VirtualEarth. The latest version of MapCruncher also supports uploading the image tiles to the highly affordable Amazon S3 service.

 

Here are some the Yahoo! MapMixer maps that I created playing around with the service.

Fort Collins Map

Colorado Regional Map

"Task List" feature in Visual Studio 2005

Posted in Visual Studio 2005 by viswaug on September 7, 2007

Technorati Tags:

One of the less known features in Visual Studio is the “Task List” window. It helps you maintain a “To Do” list of sorts inside Visual Studio 2005. I, personally wasn’t aware of this feature until sometime last year and found this feature to be very handy at times.

TaskList1

When you select “Comments” from the drop down list on the top, you will see a list of all the places where you have used a ‘TODO: in your code. The “TODO” here acts as an identifier and any comment that starts with ‘TODO: can be seen the list inside the “Task List” window. This list also acts as bookmarks. Double-clicking any item in the list takes you to the file and line where ‘TODO: is found. There are a couple of other identifier that are in Visual Studio 2005 by default. New identifier tags can also be added as required in the “Tools” -> Options” dialog. In the “Options” dialog, select the “Environment -> Task List” option on the left pane. The screen below shows how to add a new identifier.

IdentiferList

AddNewIdentifier

Now any comment in your code that starts with an ‘REFACTOR: will also be listed in the “Task List” window.

RefactorAdded

When you select “User Tasks” from the drop down list on the top, the “Task List” window displays a list where new tasks can be added. This a a real simple list where you can add and manage task items that you need to keep track of. When a task is completed, the checkbox on the task item can be checked, which will strike the text in the task. Even though these features may not meet all the requirements for a good “To Do” list, it is handy and can be used in moderation to be useful.

An abstract base class to facilitate persistence in the ESRI framework

Posted in Uncategorized by viswaug on September 7, 2007
Technorati Tags: ,

There are different ways in which .NET types can be persisted using the ESRI persistence framework. Personally, I use an “sbPersistable” abstract base class to make the persistence easier. The sbPersistable is an utility class that can be inherited by classes that need to persist and rehydrate themselves to a stream. It implements most of the common methods required for persistence and only requires the implementing classes to store and retrieve their properties from its PersistPropertySet property. A sample class that implements and uses sbPersistable to support persistence is shown below. In the example, the implementing class simply overrides the ToPropertySet() and the FromPropertySet() methods to achieve its persistence.

Public Class PersistenceSample

    Inherits sbPersistable

 

    Private _name As String

    Private _age As Integer

 

    Public Property Name() As String

        Get

            Return _name

        End Get

        Set(ByVal value As String)

            _name = value

        End Set

    End Property

 

    Public Property Age() As Integer

        Get

            Return _age

        End Get

        Set(ByVal value As Integer)

            _age = value

        End Set

    End Property

 

    Public Overloads Overrides Sub ToPropertySet()

 

        MyBase.ToPropertySet()

        PersistPropertySet.SetProperty(“Name”, _name)

        PersistPropertySet.SetProperty(“Age”, _age)

 

    End Sub

 

    Public Overloads Overrides Sub FromPropertySet()

 

        MyBase.FromPropertySet()

        _name = DirectCast(PersistPropertySet.GetProperty(“Name”), String)

        _age = DirectCast(PersistPropertySet.GetProperty(“Age”), Integer)

 

    End Sub

 

End Class

The class stores all its properties into a “PropertySet” and persists and rehydrates the “PropertySet” as a whole instead of persisting and rehydrating each property individually. The “sbPersistable” class also implements a couple of other interfaces “IsbClassID” and “IsbClassInstanceID” that enable applications using the class to identify and compare objects even after persistence and rehydration. The “sbPersistable” class and other utility classes can be downloaded here.

    ”’ <summary>

    ”’ Provides access to members used to persist objects

    ”’ </summary>

    <Guid(“658CE48F-D5D4-4aa5-BC0C-AD542326C69E”)> _

    <ProgId(“Common.GIS.sbPersistable”), ClassInterface(ClassInterfaceType.None)> _

    Public MustInherit Class sbPersistable

        Implements IsbPersistable

        Implements IsbClassID

        Implements IsbClassInstanceID

 

        Protected _persistPropertySet As IPropertySet = New PropertySet()

        Private _classInstanceID As String = Guid.NewGuid().ToString()

 

        Public Sub New()

            _classInstanceID = Guid.NewGuid().ToString()

        End Sub

 

#Region “IsbClassID Members”

 

        Public ReadOnly Property ClassID() As String Implements IsbClassID.ClassID

            Get

                Return Me.GetType().GUID.ToString()

            End Get

        End Property

 

#End Region

 

#Region “IsbClassInstanceID Members”

 

        Public ReadOnly Property ClassInstanceID() As String Implements IsbClassInstanceID.ClassInstanceID

            Get

                Return _classInstanceID

            End Get

        End Property

 

#End Region

 

#Region “IsbPersistable Members”

 

        Public Property PersistPropertySet() As IPropertySet Implements IsbPersistable.PersistPropertySet

            Get

                Return _persistPropertySet

            End Get

            Set(ByVal value As IPropertySet)

                _persistPropertySet = value

            End Set

        End Property

 

        Public Overridable Sub ToPropertySet() Implements IsbPersistable.ToPropertySet

 

            PersistPropertySet.SetProperty(“ClassInstanceID”, ClassInstanceID)

 

        End Sub

 

        Public Overridable Sub FromPropertySet() Implements IsbPersistable.FromPropertySet

 

            _classInstanceID = DirectCast(PersistPropertySet.GetProperty(“ClassInstanceID”), String)

 

        End Sub

 

#End Region

 

#Region “IPersistStream Members”

 

        Public Sub GetClassID(ByRef pClassID As Guid) Implements IPersistStream.GetClassID, IPersist.GetClassID

            pClassID = Me.GetType().GUID

        End Sub

 

        Public Sub GetSizeMax(ByRef pcbSize As ESRI.ArcGIS.esriSystem._ULARGE_INTEGER) Implements IPersistStream.GetSizeMax

            pcbSize = New _ULARGE_INTEGER()

            pcbSize.QuadPart = CType(Marshal.SizeOf(PersistPropertySet), ULong)

        End Sub

 

        Public Sub IsDirty() Implements IPersistStream.IsDirty

 

        End Sub

 

        Public Sub Load(ByVal pstm As ESRI.ArcGIS.esriSystem.IStream) Implements IPersistStream.Load

            Try

                PersistPropertySet = New PropertySetClass()

                TryCast(PersistPropertySet, ESRI.ArcGIS.esriSystem.IPersistStream).Load(pstm)

                FromPropertySet()

            Catch ex As Exception

                Throw New Exception(“An unexpected error occurred while rehydrating object from stream.”, ex)

            End Try

        End Sub

 

        Public Sub Save(ByVal pstm As ESRI.ArcGIS.esriSystem.IStream, ByVal fClearDirty As Integer) Implements IPersistStream.Save

            Try

                ToPropertySet()

                TryCast(PersistPropertySet, ESRI.ArcGIS.esriSystem.IPersistStream).Save(pstm, fClearDirty)

            Catch ex As Exception

                Throw New Exception(“An unexpected error occurred while persisting object to stream.”, ex)

            End Try

        End Sub

 

#End Region

 

    End Class

A generic factory utility class

Posted in Uncategorized by viswaug on September 5, 2007

Some of the projects I had worked on before required the ability to plug-in different components or features to the application after deployment. This was easily achieved using the Provider Model Design Pattern. But I found myself rewriting the method to create the objects from the type information. With .NET 2.0 and generics, I was able to write a an utility class that can create any type of object requested as a generic parameter. Writing the utility class was simple enough as can be seen below.

    public class Factory

    {

 

        #region “Private Members”

            AssemblyElementCollection _assemblyCollection;

        #endregion

 

        #region “Properties Members”

 

            public AssemblyElementCollection AssemblyCollection

            {

                get { return _assemblyCollection; }

            }

 

        #endregion

 

        #region “Constructors”

 

            public Factory(AssemblyElementCollection passemblyCollection)

            {

                _assemblyCollection = passemblyCollection;

            }

 

        #endregion

 

        #region “Public Methods”

 

            public T Create<T>(string pkey, params object[] pargs) where T : class

            {

                Type currentType = typeof(T);

                if (!(currentType.IsClass || currentType.IsInterface))

                {

                    throw new ArgumentException(“The Create function can only be called on interfaces and classes.”, “T”);

                }

 

                foreach (AssemblyElement ae in AssemblyCollection)

                {

                    if (ae.Key == pkey)

                    {

                        Assembly a = Assembly.Load(ae.FileName);

                        foreach (Type typ in a.GetTypes())

                        {

                            if (ae.ClassName == typ.Name)

                            {

                                object obj = Activator.CreateInstance(typ, pargs);

 

                                if(obj.GetType() == currentType)

                                {

                                    return obj as T;

                                }

                                else

                                {

                                    throw new InvalidCastException(“Cannot convert object of type [“ + obj.GetType().FullName + “] to [“ + currentType.FullName + “].”);

                                }

                            }

                        }

                    }

                }

 

                return null;

            }

 

        #endregion

 

    }

 

The core of the above sample is the Create<T>(…) functions that takes the type to be created as the generic parameter. The generic parameter of the function can either be an interface or a class as required. The “pkey” argument of the function that identifies the name of the entry in the configuration section. The “pargs” argument can be used to pass any arguments to the constructor of the type being created. This argument can be set to NULL if the constructor of the type being created does not take any arguments. An “InvalidCastException” will be thrown if the generic parameter type specified cannot be assigned from the object created. The configuration classes “AssemblyElement” and “AssemblyElementCollection” classes referenced in the above sample can be found in the project that can be downloaded here.