in

 

Ray Houston

  • Do Anonymous Methods Prevent Declaring Types from Being GC'd?

    It seems that they do if they reference members of the declaring type. This makes perfect sense now that I think about it, but I didn't think about it earlier and wrote some code that caused a memory leak. I had an object acting as a singleton and referencing a delegate instance that was created from an object acting as a non singleton. Bam! Memory Leak.

    I setup a little test to demonstrate. Here is a class that has two methods which return delegate instances:

    public class TestSource
    {
        private string internalValue = "test";
    
        public Func<bool> GetFunc1()
        {
            return () => 1 == 1;
        }
    
        public Func<string> GetFunc2()
        {
            return () => internalValue;
        }
    }
    

    Notice that GetFunc1() doesn't have any references to internal members, but GetFunc2() does. Here's the test class:

    class Program
    {
        static void Main(string[] args)
        {
            // hold no references to TestSource
            TestFuncInstance(new TestSource().GetFunc1());
            TestFuncInstance(new TestSource().GetFunc2());
    
            Console.WriteLine("Press Enter to continue.");
            Console.ReadLine();
        }
    
        private static void TestFuncInstance(Delegate func)
        {
            Thread.Sleep(1000);// give some time for GC
    
            Console.WriteLine(string.Format("Method: {0}",func.Method));
            Console.WriteLine(string.Format("DeclaringType: {0}", func.Method.DeclaringType));
            Console.WriteLine(string.Format("Target: {0}", func.Target ?? "null"));
    
            Console.WriteLine();
        }
    }
    

    This creates two separate instances of TestSource and passes the result of the two GetFunc methods to a test method. Notice that there are no declared variable references to the TestSource object. Here's the output of the test:

    Method: Boolean <GetFunc1>b__0()
    DeclaringType: TestingDelegates.TestSource
    Target: null 
    
    Method: System.String <GetFunc2>b__2()
    DeclaringType: TestingDelegates.TestSource
    Target: TestingDelegates.TestSource 
    
    Press Enter to continue.
    

    I know this test isn't very scientific, but you'll see that Func1's target is null while Func2's target is not. Func2 has to hold a reference to the declaring object so that it can do it's job when invoked. Func1 does not need a reference, and seems to free up the declaring object to be garbage collected. This is definitely something to keep in mind when passing around delegates.

    Technorati Tags: ,,
  • Synchronizing UI Operations with Asynchronous Dependencies

    When working with asynchronous data access such as using a Silverlight client to access data from a server side service, you will inevitably run into the situation where you have two or more calls which have results that need to be processed in a synchronous manner. A simple example is populating a list box from server side data and then making a second call to get the value that needs to be selected. You could wait until the list is populated before making the second call, but that would be a waste.

    I built a little helper object that allows you to define Action delegates that will get executed in a specific order once all pending operations have completed. Below is a snippet of how it can be used.

    private ILoginService loginService;
    private ILoginView loginView;
    private OperationSync localeOpSync = 
            new OperationSync(LocaleOps.GetLocales, LocaleOps.GetDefaultLocale);
    
    private void PopulateLocales()
    {
        loginService.GetLocales(HandleGetLocalesResult);
        loginService.GetDefaultLocale(HandleGetDefaultLocaleResult);
    }
    
    private void HandleGetDefaultLocaleResult(string result)
    {
        localeOpSync.OpCompleted(LocaleOps.GetDefaultLocale, GetSetSelectedLocaleAction(result));
    }
    
    private void HandleGetLocalesResult(string[] result)
    {
        localeOpSync.OpCompleted(LocaleOps.GetLocales, GetSetLocaleSelectionAction(result));
    }
    
    private Action GetSetSelectedLocaleAction(string result)
    {
        return () => loginView.SetSelectedLocale(result);
    }
    
    private Action GetSetLocaleSelectionAction(string[] result)
    {
        return ()=> loginView.SetLocaleSelections(result);
    }
     
    In this example, there are two asynchronous service methods which get called. Their results are passed to handler methods where they are processed by Actions, but those Actions don't execute until both OpComplete methods have fired (actually the last OpComplete triggers the execution of all the Actions. It doesn't matter which call returns first. Their associated Actions will execute in the order defined by the keys in the creation of the OperationSync object. There are a million different ways to put this together with lambdas and anonymous methods, but I tried to bust it up here so it would be easier to follow.

    To show how it works I've included a subset of the unit tests (with extension methods and other goodies stripped out). The setup for all the specs is at the bottom of the code snippet.

    [TestFixture]
    public class when_not_completing_all_ops 
        : behaves_like_setting_up_operation_actions
    {
        [Test]
        public void should_not_execute_actions()
        {
            OpSync.OpCompleted(OpKey.One, Action1);
            OpSync.OpCompleted(OpKey.Two, Action2);
    
            CollectionAssert.IsEmpty(ActionResults);
        }
    }
    
    [TestFixture]
    public class when_completing_all_ops_in_key_order 
        : behaves_like_setting_up_operation_actions
    {
        [Test]
        public void should_execute_actions_in_key_order()
        {
            OpSync.OpCompleted(OpKey.One, Action1);
            OpSync.OpCompleted(OpKey.Two, Action2);
            OpSync.OpCompleted(OpKey.Three, Action3);
    
            Assert_That_ActionResults_Fire_In_Correct_Order();
        }
    }
    
    [TestFixture]
    public class when_completing_all_ops_not_in_key_order 
        : behaves_like_setting_up_operation_actions
    {
        [Test]
        public void should_execute_actions_in_key_order()
        {
            OpSync.OpCompleted(OpKey.Two, Action2);
            OpSync.OpCompleted(OpKey.Three, Action3);
            OpSync.OpCompleted(OpKey.One, Action1);
    
            Assert_That_ActionResults_Fire_In_Correct_Order();
        }
    }
    
    public abstract class behaves_like_setting_up_operation_actions
    {
        protected OperationSync OpSync { get; set; }
        protected Action Action1 { get; set; }
        protected Action Action2 { get; set; }
        protected Action Action3 { get; set; }
        protected List<OpKey> ActionResults { get; set; }
    
        [SetUp]
        public void Before_Each_Spec()
        {
            OpSync = new OperationSync(OpKey.One, OpKey.Two, OpKey.Three);
    
            Action1 = () => ActionResults.Add(OpKey.One);
            Action2 = () => ActionResults.Add(OpKey.Two);
            Action3 = () => ActionResults.Add(OpKey.Three);
    
            ActionResults = new List<OpKey>();
        }
    
        protected void Assert_That_ActionResults_Fire_In_Correct_Order()
        {
            Assert.That(ActionResults.Count, Is.EqualTo(3));
            Assert.That(ActionResults[0], Is.EqualTo(OpKey.One));
            Assert.That(ActionResults[1], Is.EqualTo(OpKey.Two));
            Assert.That(ActionResults[2], Is.EqualTo(OpKey.Three));
        }
    
        protected enum OpKey
        {
            One,
            Two,
            Three
        }
    }
    

    The keys can be anything. I have just been creating a private enum in the class where I need them. Here's the OperationSync class that handles it all:

    public class OperationSync
    {
        private static readonly object syncRoot = new object();
    
        private readonly object[] keys;
        private readonly Dictionary<object, bool> keyKeepActionAfterExecute = 
            new Dictionary<object, bool>();
    
        private readonly Dictionary<object, Action> keyActions = 
            new Dictionary<object, Action>();
    
        public OperationSync(params object[] operationKeys)
        {
            keys = operationKeys;
    
            foreach (var o in operationKeys)
            {
                keyActions.Add(o, null);
            }
        }
    
        public void OpCompleted(object key, Action action)
        {
            OpCompleted(key, action, false);
        }
    
        public void OpCompleted(object key, Action action, bool keepActionAfterExecute)
        {
            lock (syncRoot)
            {
                if (!keyActions.ContainsKey(key))
                    throw new UIException("Key '{0}' not found.");
    
                keyActions[key] = action;
                keyKeepActionAfterExecute[key] = keepActionAfterExecute;
    
                if (AllOpsComplete())
                    ProcessActions();
            }
        }
    
        private void ProcessActions()
        {
            ExecuteEachAction();
    
            ClearActionsIfIndicated();
        }
    
        private void ExecuteEachAction()
        {
            foreach (var key in keys)
            {
                keyActions[key]();
            }
        }
    
        private void ClearActionsIfIndicated()
        {
            foreach (var key in keys)
            {
                if (!keyKeepActionAfterExecute[key])
                    keyActions[key] = null;
            }
        }
    
        private bool AllOpsComplete()
        {
            return keyActions.All(pair => pair.Value != null);
        }
    }
    

    There's probably a fancy smancy AJAX pattern name for this sort of thing. Let me know if you come across one.

    Technorati Tags: ,,,

  • Connecting ActiveRecord to SQL Server

    Disclaimer: I'm a Ruby noobie. I know nada about Rails. Please leave a comment if something is not correct or if there is a better way to do this.

    At work, we're using Watir to drive a Silverlight application for some automated end to end testing. We needed an easy way to access the database from our RSpec test fixtures to make sure the proper setup data is put where we need it. I discovered that ActiveRecord can be used without rails and that all I needed to do was just install the gem. Typing the following seemed to do the trick for me:

    gem install activerecord

    I then found this which told me that I have install the SQLServer adapter separately like so:

    gem install activerecord-sqlserver-adapter --source=http://gems.rubyonrails.org

    It then also says that one must get the latest source distribution of Ruby-DBI from here and copy the file:

    lib/dbd/ADO.rb

    to your Ruby installation directory in the following place:

    X:/ruby/lib/ruby/site_ruby/1.8/DBD/ADO/ADO.rb

    After that I was able to create a simple test page to see if could actually get connected.

    ActiveRecordTest.rb

    require 'active_record'
    
    ActiveRecord::Base.pluralize_table_names = false
    
    ActiveRecord::Base.establish_connection(
        :adapter => "sqlserver",
        :host => ".\\SQLEXPRESS",
        :database => "MyDB",
        :username => "sa",
        :password => "sa"
    )
    
    class Customer < ActiveRecord::Base
    end
    
    Customer.find(:all).each do |cust| puts cust.Name end

    This test selects all the customers and outputs their names.

    Technorati Tags: ,
  • Funding Open Source with Donations

    Read this post! I'm challenging you to make a difference.

    I was part of the Funding Open Source Projects discussion at the ALT.NET conference. Oren has a good summary which can be found here. He mentions that donations sound good, but really don't work. I think that's a shame. I have these thoughts that we as a community could do some really cool things if we work together get things done.

    I want to try a little experiment using the current buzz around the ALT.NET conference. I challenge 5+ volunteers to donate $$ to their favorite OS project and say that they did so on their blogs and then challenge 5+ more volunteers to do the same. If you don't have a blog, then post a comment here saying you donated.

    I donated to Oren's Open Source efforts.

    Don't put it off. Do it now. Blog it. Tweet it. Spread the word! Donate!

    UPDATE: Donating time to Open Source Projects counts too!

    UPDATE: One thing that $$ could help out with is hiring someone to do documentation. Oren said that working on open source projects is his hobby and that's why he does it. He also said that he doesn't like to do documentation and that is not his hobby. I don't know any developers that like to do documentation.

  • Thanks ALT.NET Seattle

    The ALT.NET conference wrapped up yesterday afternoon. I wanted to say thanks to all the volunteers, organizers, and sponsors. Thanks to all the other participants who made up the conference. I got to meet a lot of folks who I had only previously known online and I got to be involved in many interesting conversations. I even got to see some snow coming down. It was a very productive conference.

    I wanted to give a special thanks to all the Microsoft folks that attended the conference. Those guys get beat up a lot sometimes and I am very impressed by how well they respond to criticism. My hat goes off to those guys for taking the criticism and responding in positive ways. I have a lot of respect for those folks.

    Software is hard. Perhaps we will eventually evolve software development into something that's not hard. Perhaps there will be some completely new radical idea which makes the software development we do today become part of history books. Until then it's all really about striving to suck less. It seems that whatever gets labeled as the right way of doing things is really just a way to suck less.

    So here's my definition of ALT.NET - People helping each other to suck less.

  • Influence Change

    It's easy to get bogged down in our jobs and forget that we have the power to make changes. You may not have the authority to make changes yourself, but you always have the power to influence other people. Part of working at a company is working with others and that often means that you'll have ideas that you'll need other people's help to execute. I've worked at a lot of places where people are reluctant to change, but there have been very few places that completely refused to change.

    In order to get people to change, you have to educate them on how the change will make their jobs better. Nobody will want to change if they think it will cause them more work. Listen and get to know other people and find out about their work. Find out what things are important to them. How will your ideas help them? Persuade people by showing real value.

    Convincing people often takes more than one conversation. Sometimes it takes years! Some folks are more influential than others, but we all possess the ability. You won't always be successful in influencing people to come around to your way of thinking, but you'll probably be more successful than you think if you're mindful of it. Think about how you are influenced and use that as a tool to influence others.

  • Creating a Timestamp Interceptor in NHibernate

    In a previous post, I gave an example of a Timestamp class and how one might create an ICompositeUserType to map it within NHibernate. Here I want to show of an example of an IInterceptor which will automatically populate the values for my Timestamp class. OnSave is for the inserts, and OnFlushDirty is for the updates. There are a bunch of other methods that you can tap into for different things, so check out the NHibernate docs.
     
    public class TimestampInterceptor : EmptyInterceptor
    {
        private const string TIMESTAMP_PROPERTY = "Timestamp";
    
        private readonly IDomainContext domainContext;
        private readonly ISystemClock clock;
    
        public TimestampInterceptor(IDomainContext domainContext, ISystemClock clock)
        {
            this.domainContext = domainContext;
            this.clock = clock;
        }
    
        public override bool OnSave(object entity, object id, object[] state, 
            string[] propertyNames, IType[] types)
        {
            var timestampable = entity as ITimestampable;
    
            if(timestampable == null)
                return false;
    
            var timestamp = GetTimestamp(state, propertyNames);
    
            timestamp.CreatedDateTime = clock.Now();
    
            if (domainContext.DomainUser != null)
                timestamp.CreatedByStaff = domainContext.DomainUser.StaffName;
    
            return true;
        }
    
        public override bool OnFlushDirty(object entity, object id, object[] currentState, 
            object[] previousState, string[] propertyNames, IType[] types)
        {
            var timestampable = entity as ITimestampable;
    
            if (timestampable == null)
                return false;
    
            var timestamp = GetTimestamp(currentState, propertyNames);
    
            timestamp.UpdatedDateTime = clock.Now();
    
            if(domainContext.DomainUser != null)
                timestamp.UpdatedByStaff = domainContext.DomainUser.StaffName;
    
            return true;
        }
    
        private static Timestamp GetTimestamp(object[] state, string[] propertyNames)
        {
            var timestamp = state[Array.IndexOf(propertyNames, TIMESTAMP_PROPERTY)] as Timestamp;
    
            if( timestamp == null )
            {
                timestamp = new Timestamp();
                state[Array.IndexOf(propertyNames, TIMESTAMP_PROPERTY)] = timestamp;
            }
    
            return timestamp;
        }
    }
     
    I haven't run this through the ringers yet, so let me know if you spot some problems.
    Technorati Tags: ,
  • A Simple Closure To Handle Try/Catch Around Transactions

    (Updated: I moved the begin transaction outside of the try as Chad suggested in the comments.)

    If you're like me, you're lazy and hate putting try/catch around your transaction handling in your code. It has to be there, but it's just a pain. You may have code that looks something like:

    domainContext.BeginTransaction();
    
    try
    {
        historicalPwdService.RecordHistoricalPassword(user.UserProfileID, currentPassword);
    
        user.Password = newPassword;
        user.PasswordCreateDate = systemClock.Now();
    
        userProfileRepo.Save(user);
    
        domainContext.CommitTransaction();
    }
    catch
    {
        domainContext.RollbackTransaction();
        throw;
    }
    

    Well here's a little helper class that can ease the pain a bit:

    public static class WorkUnit
    {
        public static void Do(IDomainContext context, Action workUnit)
        {
            context.BeginTransaction();
    
            try
            {
                workUnit();
                    
                context.CommitTransaction();
            }
            catch
            {
                context.RollbackTransaction();
    
                throw;
            }
        }
    }
    

    now you can use it with an anonymous method:

    WorkUnit.Do(domainContext, ()=>
        {
            historicalPwdService.RecordHistoricalPassword(user.UserProfileID, currentPassword);
    
            user.Password = newPassword;
            user.PasswordCreateDate = systemClock.Now();
    
            userProfileRepo.Save(user);
        });
    

    Side note for Jimmy: You should be proud. I went back and switched out my custom delegate for Action. ;)

    Technorati Tags: ,
  • Mapping Timestamp Data Using NHibernate's ICompositeUserType

    In my previous post, I took some string data and mapped it directly to a boolean property on an entity. That was pretty simple, but I wanted to try it out on a little more complex object..

    In our projects, most of the entities have a Timestamp property which is of type Timestamp:

    public class User
    {
        public string UserID { get; set; }
        public string Username { get; set; }
        public string Password { get; set; }
        public Timestamp Timestamp { get; set; }
    }

    and here's the Timestamp class:

    public class Timestamp
    {
        public string CreatedByStaff { get; set; }
        public string UpdatedByStaff { get; set; }
        public DateTime? CreatedDateTime { get; set; }
        public DateTime? UpdatedDateTime { get; set; }
    }
    

    In the database, the USER table would have the obvious columns for UserID, Username, and Password, but also have the columns for the Timestamp which in my case are CREATED_BY_STAFF, UPDATED_BY_STAFF, CREATED_DATETIME, and UPDATED_DATETIME. Now this can easily be mapped as it is by using a component like so:

    <component name="Timestamp" class="XYZ.Core.Timestamp, XYZ.Core">
      <property name="CreatedByStaff" type="String" column="CREATED_BY_STAFF" not-null="true"/>
      <property name="UpdatedByStaff" type="String" column="UPDATED_BY_STAFF" not-null="false"/>
      <property name="CreatedDateTime" type="DateTime" column="CREATED_DATETIME" not-null="true"/>
      <property name="UpdatedDateTime" type="DateTime" column="UPDATED_DATETIME" not-null="false"/>
    </component>
    

    That works well, but I hate having to repeat that all over the place. I would rather just have one single line that maps a Timestamp. I experimented with creating a custom mapping type using the ICompositeUserType and got a little closer to the goal. Here's the class:

    public class TimestampMappingType : ICompositeUserType
    {
        public bool IsMutable
        {
            get { return true; }
        }
    
        public Type ReturnedClass
        {
            get { return typeof(Timestamp); }
        }
    
        public string[] PropertyNames
        {
            get { return new[] { "CreatedByStaff", "UpdatedByStaff", "CreatedDateTime", "UpdatedDateTime" }; }
        }
    
        public IType[] PropertyTypes
        {
            get { return new[] { NHibernateUtil.String, NHibernateUtil.String, NHibernateUtil.DateTime, NHibernateUtil.DateTime}; }
        }
    
        public object Assemble(object cached, ISessionImplementor session, object owner)
        {
            return DeepCopy(cached);
        }
    
        public object GetPropertyValue(object component, int property)
        {
            var timestamp = AsTimestamp(component);
    
            switch(property)
            {
                case 0:
                    return timestamp.CreatedByStaff;
                case 1:
                    return timestamp.UpdatedByStaff;
                case 2:
                    return timestamp.CreatedDateTime;
                case 3:
                    return timestamp.UpdatedDateTime;
                default:
                    throw new YourException("No implementation for property index of '{0}'.", property);
            }
        }
    
        public void SetPropertyValue(object component, int property, object value)
        {
            if (component == null)
                throw new ArgumentNullException("component");
    
            var timestamp = AsTimestamp(component);
            switch (property)
            {
                case 0:
                    timestamp.CreatedByStaff = (string)value;
                    break;
                case 1:
                    timestamp.UpdatedByStaff = (string)value;
                    break;
                case 2:
                    timestamp.CreatedDateTime = (DateTime?)value;
                    break;
                case 3:
                    timestamp.UpdatedDateTime = (DateTime?)value;
                    break;
                default:
                    throw new YourException("No implementation for property index of '{0}'.", property);
            }           
        }
    
        public object NullSafeGet(IDataReader dr, string[] names, ISessionImplementor session, object owner)
        {
            var createdByStaff = NHibernateUtil.String.NullSafeGet(dr, names[0]);
            var updatedByStaff = NHibernateUtil.String.NullSafeGet(dr, names[1]);
            var createdDateTime = NHibernateUtil.DateTime.NullSafeGet(dr, names[2]);
            var updatedDateTime = NHibernateUtil.DateTime.NullSafeGet(dr, names[3]);
    
            return new Timestamp
            {
                CreatedByStaff = (string)createdByStaff,
                UpdatedByStaff = (string)updatedByStaff,
                CreatedDateTime = (DateTime?)createdDateTime,
                UpdatedDateTime = (DateTime?)updatedDateTime
            };
        }
    
        public void NullSafeSet(IDbCommand cmd, object value, int index, ISessionImplementor session)
        {
            if (value == null)
            {
                ((IDataParameter)cmd.Parameters[index]).Value = DBNull.Value;
                ((IDataParameter)cmd.Parameters[index+1]).Value = DBNull.Value;
                ((IDataParameter)cmd.Parameters[index+2]).Value = DBNull.Value;
                ((IDataParameter)cmd.Parameters[index+3]).Value = DBNull.Value;
            }
            else
            {
                var timestamp = AsTimestamp(value);
    
                ((IDataParameter)cmd.Parameters[index]).Value = (object)timestamp.CreatedByStaff ?? DBNull.Value;
                ((IDataParameter)cmd.Parameters[index + 1]).Value = (object)timestamp.UpdatedByStaff ?? DBNull.Value;
                ((IDataParameter)cmd.Parameters[index + 2]).Value = (object)timestamp.CreatedDateTime ?? DBNull.Value;
                ((IDataParameter)cmd.Parameters[index + 3]).Value = (object)timestamp.UpdatedDateTime ?? DBNull.Value;
            }
        }
    
        public object DeepCopy(object value)
        {
            if(value == null) return null;
    
            var original = AsTimestamp(value);
    
            return new Timestamp
                       {
                            CreatedByStaff = original.CreatedByStaff, 
                            UpdatedByStaff = original.UpdatedByStaff,
                            CreatedDateTime = original.CreatedDateTime,
                            UpdatedDateTime = original.UpdatedDateTime
                        };
        }
    
        public object Disassemble(object value, ISessionImplementor session)
        {
            return DeepCopy(value);
        }
    
        public object Replace(object original, object target, ISessionImplementor session, object owner)
        {
            return DeepCopy(original);
        }
    
        public new bool Equals(object x, object y)
        {
            if (ReferenceEquals(x, y)) return true;
    
            if (x == null || y == null) return false;
    
            return x.Equals(y);
        }
    
        public int GetHashCode(object x)
        {
            return x == null ? typeof(Timestamp).GetHashCode() + 321 : x.GetHashCode();
        }
    
        private static Timestamp AsTimestamp(object value)
        {
            if (value == null) return null;
    
            var ts = value as Timestamp;
    
            if(ts == null)
                throw new YourException("Expected '{0}' but recieved '{1}'.", typeof(Timestamp), value.GetType());
    
            return ts;
        }
    }

    Using this class in my mapping, I can now shorten the Timestamp mapping to:

    <property name="Timestamp" type="XYZ.DataAccess.TimestampMappingType, XYZ.DataAccess">
      <column name="CREATED_BY_STAFF" />
      <column name="UPDATED_BY_STAFF" />
      <column name="CREATED_DATETIME" />
      <column name="UPDATED_DATETIME" />
    </property>
    

    That's a little better but I was hoping I could get away with not having to define the columns (they're the same on every table) but I don't see a way to set defaults (maybe I'm in the wrong place?). In the end, I'm not sure this really buys me much more than just mapping Timestamp as a component, but I'll poke around a little more to see if I can figure it out.

    Technorati Tags: ,
  • Mapping Strings to Booleans Using NHibernate's IUserType

    Update: I failed to realized that the functionality of converting "Y" or "N" to a boolean is already built into NHibernate by doing type="YesNo" (see comments). I'll leave this post up just for the academics of creating a IUserType. Go figure that I would come up with something that's built in!

    We have some legacy data where boolean values are stored as strings. "Y" is true and "N" is no. We're also creating entities which have properties that map to this data. It would be just plain evil to have to create all the boolean properties as strings! We previously solved this problem by creating our own .NET type that had a string property for the "Y" or "N" value. This type had an implicit cast defined as a bool, so we could treat it as a boolean in expressions and assignments. We mapped this in NHibernate as a component with the single string property and this worked pretty well, but I suspected that there was a better way. Today I bought the e-book version of NHibernate in Action and quickly read through the section on creating an implementation of IUserType. I then came up with the following class that allows me to keep my types as true booleans in the code.

    public class YesNoType : IUserType
    {
        public bool IsMutable
        {
            get { return false; }
        }
    
        public Type ReturnedType
        {
            get { return typeof(YesNoType); }
        }
    
        public SqlType[] SqlTypes
        {
            get { return new[]{NHibernateUtil.String.SqlType}; }
        }
    
        public object NullSafeGet(IDataReader rs, string[] names, object owner)
        {
            var obj = NHibernateUtil.String.NullSafeGet(rs, names[0]);
    
            if(obj == null ) return null;
    
            var yesNo = (string) obj;
    
            if( yesNo != "Y" && yesNo != "N" )
                throw new YourException("Expected data to be 'Y' or 'N' but was '{0}'.", yesNo);
    
            return yesNo == "Y";
        }
    
        public void NullSafeSet(IDbCommand cmd, object value, int index)
        {
            if(value == null)
            {
                ((IDataParameter) cmd.Parameters[index]).Value = DBNull.Value;
            }
            else
            {
                var yes = (bool) value;
                ((IDataParameter)cmd.Parameters[index]).Value = yes ? "Y" : "N";
            }
        }
    
        public object DeepCopy(object value)
        {
            return value;
        }
    
        public object Replace(object original, object target, object owner)
        {
            return original;
        }
    
        public object Assemble(object cached, object owner)
        {
            return cached;
        }
    
        public object Disassemble(object value)
        {
            return value;
        }
    
        public new bool Equals(object x, object y)
        {
            if( ReferenceEquals(x,y) ) return true;
    
            if( x == null || y == null ) return false;
    
            return x.Equals(y);
        }
    
        public int GetHashCode(object x)
        {
            return x == null ? typeof(bool).GetHashCode() + 473 : x.GetHashCode();
        }
    }
    

    The mapping looks something like:

    <property name="Active" type="NHTypes.YesNoType, NHTypes" column="ACTIVE_YN" not-null="false" />

    I'm not going to go into detail and explain what all the parts are and do (see link), but I thought that I would share the class. Please let me know if you spot any problems.

    Technorati Tags: ,
  • PTOM: The Interface Segregation Principle

    In following suite with the The Los Techies Pablo's Topic of the Month - March: SOLID Principles, I chose to write a little about the The Interface Segregation Principle (ISP). As Chad pointed out with LSP, the ISP is also one of Robert 'Uncle Bob' Martin's S.O.L.I.D design principles.

    Basically ISP tells us that clients shouldn't be forced to implement interfaces they don't use. In other words, if you have an abstract class or an interface, then the implementers should not be forced to implement parts that they don't care about.

    I was having trouble thinking of a real world example for ISP but then was reminded about implementing a custom Membership Provider in ASP.NET 2.0. I had completely blocked that monstrosity out of my mind (for good reason).

    The Membership Provider was a way to integrate with some of the ASP.NET's built in management of users and its associated server controls. For me, it ended up being a lot more trouble than it was worth, but it turns out to be a good example of a fat interface. In order to implement your own Membership Provider you "simply" implement the abstract class MembershipProvider like so:

    public class CustomMembershipProvider : MembershipProvider
    {
        public override string ApplicationName
        {
            get
            {
                throw new Exception("The method or operation is not implemented.");
            }
            set
            {
                throw new Exception("The method or operation is not implemented.");
            }
        }
    
        public override bool ChangePassword(string username, string oldPassword, string newPassword)
        {
            throw new Exception("The method or operation is not implemented.");
        }
    
        public override bool ChangePasswordQuestionAndAnswer(string username, string password, 
            string newPasswordQuestion, string newPasswordAnswer)
        {
            throw new Exception("The method or operation is not implemented.");
        }
    
        public override MembershipUser CreateUser(string username, string password, string email, 
            string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, 
            out MembershipCreateStatus status)
        {
            throw new Exception("The method or operation is not implemented.");
        }
    
        public override bool DeleteUser(string username, bool deleteAllRelatedData)
        {
            throw new Exception("The method or operation is not implemented.");
        }
    
        public override bool EnablePasswordReset
        {
            get { throw new Exception("The method or operation is not implemented."); }
        }
    
        public override bool EnablePasswordRetrieval
        {
            get { throw new Exception("The method or operation is not implemented."); }
        }
    
        public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, 
            int pageSize, out int totalRecords)
        {
            throw new Exception("The method or operation is not implemented.");
        }
    
        public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, 
            int pageSize, out int totalRecords)
        {
            throw new Exception("The method or operation is not implemented.");
        }
    
        public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
        {
            throw new Exception("The method or operation is not implemented.");
        }
    
        public override int GetNumberOfUsersOnline()
        {
            throw new Exception("The method or operation is not implemented.");
        }
    
        public override string GetPassword(string username, string answer)
        {
            throw new Exception("The method or operation is not implemented.");
        }
    
        public override MembershipUser GetUser(string username, bool userIsOnline)
        {
            throw new Exception("The method or operation is not implemented.");
        }
    
        public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
        {
            throw new Exception("The method or operation is not implemented.");
        }
    
        public override string GetUserNameByEmail(string email)
        {
            throw new Exception("The method or operation is not implemented.");
        }
    
        public override int MaxInvalidPasswordAttempts
        {
            get { throw new Exception("The method or operation is not implemented."); }
        }
    
        public override int MinRequiredNonAlphanumericCharacters
        {
            get { throw new Exception("The method or operation is not implemented."); }
        }
    
        public override int MinRequiredPasswordLength
        {
            get { throw new Exception("The method or operation is not implemented."); }
        }
    
        public override int PasswordAttemptWindow
        {
            get { throw new Exception("The method or operation is not implemented."); }
        }
    
        public override MembershipPasswordFormat PasswordFormat
        {
            get { throw new Exception("The method or operation is not implemented."); }
        }
    
        public override string PasswordStrengthRegularExpression
        {
            get { throw new Exception("The method or operation is not implemented."); }
        }
    
        public override bool RequiresQuestionAndAnswer
        {
            get { throw new Exception("The method or operation is not implemented."); }
        }
    
        public override bool RequiresUniqueEmail
        {
            get { throw new Exception("The method or operation is not implemented."); }
        }
    
        public override string ResetPassword(string username, string answer)
        {
            throw new Exception("The method or operation is not implemented.");
        }
    
        public override bool UnlockUser(string userName)
        {
            throw new Exception("The method or operation is not implemented.");
        }
    
        public override void UpdateUser(MembershipUser user)
        {
            throw new Exception("The method or operation is not implemented.");
        }
    
        public override bool ValidateUser(string username, string password)
        {
            throw new Exception("The method or operation is not implemented.");
        }
    }
    

    Holy guacamole! That's a lot of stuff. Sorry for the code puke there, but wanted you to feel a little pain as I did trying to actually implement this thing. Hopefully you didn't get tired of scrolling through that and you're still with me. ;)

    It turns out that you don't have to implement the parts you don't need, but this clearly violates the Interface Segregation Principle. This interface is extremely fat and not cohesive. A better approach would have been to break it up into smaller interfaces that allow the implementers to only worry about the parts that they need. I'm not going to go into the details of splitting this up, but I think you get the idea.

    Since I cannot think of another real world example, let's look at a completely bogus example. Say you have the following code:

    public abstract class Animal
    {
        public abstract void Feed();
    }
    
    public class Dog : Animal
    {
        public override void Feed()
        {
            // do something
        }
    }
    
    public class Rattlesnake : Animal
    {
        public override void Feed()
        {
            // do something
        }
    }
    

    But then you realize that you have a need for some of the animals to be treated as pets and have them groomed. You may be tempted to do

    public abstract class Animal
    {
        public abstract void Feed();
        public abstract void Groom();
    }
    

    which would be fine for the Dog, but it may not be fine for the Rattlesnake (although I'm sure there is some freako out there that grooms their pet rattlesnake)

    public class Rattlesnake : Animal
    {
        public override void Feed()
        {
            // do something
        }
    
        public override void Groom()
        {
            // ignore - I'm not grooming a freaking rattlesnake
        }
    }
    

    Here we have violated the ISP by polluting our Animal interface. This requires us to implement a method that doesn't make sense for the Rattlesnake object. A better choice would to implement an IPet interface which just Dog could implement and without affecting Rattlesnake. You might end up with something like this:

    public interface IPet
    {
        void Groom();
    }
    
    public abstract class Animal
    {
        public abstract void Feed();
    }
    
    public class Dog : Animal, IPet
    {
        public override void Feed()
        {
            // do something
        }
    
        public void Groom()
        {
            // do something
        }
    }
    
    public class Rattlesnake : Animal
    {
        public override void Feed()
        {
            // do something
        }
    }
    

    I think the key is if you find yourself creating interfaces that don't get fully implemented in its clients, then that's a good sign that you're violating the ISP. You can check out the link to this pdf for more complete information on the subject.

    Technorati Tags: ,,
    Posted Mar 14 2008, 11:04 PM by Ray Houston with 8 comment(s)
    Filed under:
  • A Simple Delegate Example

    I was recently working on a code generator and I made use of some simple delegates and I thought that I would share a few ideas.

    Some folks may be wondering what is a delegate.  You can think of a delegate as a type safe function pointer. It's a type which can be passed around like any other type and it can be invoked which calls the original method that it's pointing to. Lets look at a delegate type declaration:

    public delegate void DoSomething();

    This basically creates a delegate type called DoSomething that can point to a method that takes no arguments and returns void.

    Say you have a method:

    public void HeresSomething()
    {
        //put something here
    }
    

    then you can create a new instance of our delegate and have it point to that method like:

    DoSomething myDelegate = new DoSomething(HeresSomething);

    ReSharper tells me that you can abbreviate this syntax like so:

    DoSomething myDelegate = HeresSomething;

    Now myDelegate can be passed around and then executed just like a method which will call the real method HeresSomething():

    myDelegate();

    This becomes really valuable is when you have delegates that take arguments and return values as you will see in a moment.

    In my particular real life case, I have some .NET data transfer objects (DTOs) which I want to code generate equivalent Flex ActionScript objects so I can move data back and forth via serialization. These DTOs can be complex types (objects within objects) so I will need to unwind the object hierarchy to determine what to generate.

    Let's look at an example without using delegates:

    class TypeUnwinder
    {
        public void Unwind(Type type, List<Type> allTypes)
        {
            if (allTypes.Contains(type))
                return;
    
            allTypes.Add(type);
    
            UnwindProperties(type, allTypes);
            UnwindMethods(type, allTypes);
        }
    
        private void UnwindProperties(Type type, List<Type> allTypes)
        {
            foreach (PropertyInfo propertyInfo in type.GetProperties())
            {
                Unwind(propertyInfo.PropertyType, allTypes);
            }
        }
    
        private void UnwindMethods(Type type, List<Type> allTypes)
        {
            foreach (MethodInfo methodInfo in type.GetMethods())
            {
                Unwind(methodInfo.ReturnType, allTypes);
                UnwindParameters(methodInfo, allTypes);
            }
        }
    
        private void UnwindParameters(MethodInfo methodInfo, List<Type> allTypes)
        {
            foreach (ParameterInfo parameterInfo in methodInfo.GetParameters())
            {
                Unwind(parameterInfo.ParameterType, allTypes);
            }
        }
    }
    

    This code works ok but my real case is much more complex. I actually have to unwind a couple of different times for different reasons and I have multiple checks for attributes and I ignore certain types. I want to reuse my pattern of unwinding with different logic. I can do this using a delegate. Instead of passing a List around, I can have the UnwindType method simply call a delegate that takes a Type. The calling class supplies the delegate and figures out what to do with the Type when it's called.

    First I create a delegate that returns bool that takes one argument of type Type:

    public delegate bool DoSomethingWithTypeDelegate(Type type);

    Then we modify our class by removing the references to the List and have it take in an instance of our delegate in the constructor:

    class TypeUnwinder2
    {
        private readonly DoSomethingWithTypeDelegate doSomethingWithType;
    
        public TypeUnwinder2(DoSomethingWithTypeDelegate doSomethingWithType)
        {
            this.doSomethingWithType = doSomethingWithType;
        }
    
        public void UnwindType(Type type)
        {
            if(!doSomethingWithType(type))
                return;
    
            UnwindProperties(type);
            UnwindMethods(type);
        }
    
        private void UnwindProperties(Type type)
        {
            foreach (PropertyInfo propertyInfo in type.GetProperties())
            {
                UnwindType(propertyInfo.PropertyType);
            }
        }
    
        private void UnwindMethods(Type type)
        {
            foreach (MethodInfo methodInfo in type.GetMethods())
            {
                UnwindType(methodInfo.ReturnType);
                UnwindParameters(methodInfo);
            }
        }
    
        private void UnwindParameters(MethodInfo methodInfo)
        {
            foreach (ParameterInfo parameterInfo in methodInfo.GetParameters())
            {
                UnwindType(parameterInfo.ParameterType);
            }
        }
    }
    

    Now a calling class can control what actually happens when a Type is hit (remember, this is just example code):

    class Program
    {
        static readonly List<Type> types = new List<Type>();
    
        static void Main(string[] args)
        {
            TypeUnwinder2 unwinder = new TypeUnwinder2(IndexType);
    
            unwinder.UnwindType(typeof(SomeCustomTypeToUnwind));
    
            foreach (Type type in types)
            {
                Console.WriteLine(type.FullName);
            }
        }
    
        static bool IndexType(Type type)
        {
            if (!types.Contains(type))
            {
                types.Add(type);
                return true;
            }
    
            return false;            
        }
    }
    

    Notice how we pass in IndexType to the TypeUnwinder2 constructor (the delegate is created for you). If we wanted to see the delegate, we could have done:

    TypeUnwinder2 unwinder = new TypeUnwinder2(new DoSomethingWithTypeDelegate(IndexType));

    So adding a delegate allowed me to decouple my unwinding pattern from the work that happens as a result of the unwinding. Yeah!

    Here's a version that uses another delegate to reuse a single foreach loop. It's a bit ridiculous , but it might be fun to decipher.

    class TypeUnwinder3
    {
        private DoSomethingWithTypeDelegate doSomethingWithType;
    
        public TypeUnwinder3(DoSomethingWithTypeDelegate doSomethingWithType)
        {
            this.doSomethingWithType = doSomethingWithType;
        }
    
        public void UnwindType(Type type)
        {
            if (!doSomethingWithType(type))
                return