PredicateEx, ActionEx What?

PredicateEx, ActionEx What?

Old forum URL: forums.lhotka.net/forums/t/2502.aspx


rfphill posted on Saturday, March 10, 2007

private delegate bool predicateEx<U, V>(U obj1, V obj2);

private delegate void actionEx<U, V>(U obj1, V obj2);

private delegate void rulesAction();

What is the purpose of adding these things into the Codesmith templates for CSLA when there is no explanation for it's use?  I've looked everywhere... 

Codesmith template discussions for CSLA are spread between three different websites and help is still, at best minimal. 

 

rasupit replied on Monday, March 12, 2007

These delegates are used to allow user to inject code inside the generated code when using split partial method. predicateEx<U,V> and actionEx<U,V> works exactly like System.Action<T> and System.Predicate<T>, except they take 2 generics parameters.  If you haven't already used these generic delegates, play with List<T> and you'll find how cool these delegates work.

Consider you have generated an editable child object and you need to inject code on insert method to pass newly parent's identity id; The generated code generate as follow to allow user to inject code in Insert method:

        //delegate methods declaration
        private delegate bool predicateEx<U, V>(U obj1, V obj2);
        private predicateEx<SqlConnection, RootObject> executeInsertDelegate = null;
        private bool onExecuteInsert(SqlConnection cn, RootObject parent)
        {
            if (executeInsertDelegate != null)
                return executeInsertDelegate(cn, parent);
            return true;
        }
        private delegate void actionEx<U, V>(U obj1, V obj2);
        private actionEx<SqlCommand, RootObject> executeInsertCompleteDelegate = null;
        private void onExecuteInsertComplete(SqlCommand cm, RootObject parent)
        {
            if (executeInsertCompleteDelegate != null)
                executeInsertCompleteDelegate(cm, parent);
        }

predicateEx and actionEx allow to define methods that will take 2 parameter; in this we can pass connection and parent object. The insert method wires the above delegates as follow:
        internal void Insert(SqlConnection cn, RootObject parent)
        {
            if (!onExecuteInsert(cn, parent)) return;
            using (SqlCommand cm = cn.CreateCommand())
            {
                . . .
                cm.ExecuteNonQuery();

                . . .
                onExecuteInsertComplete(cm, parent);
            }//using
        }
The onExecuteInsert uses predicate delegate to allow user to replace the entire code by returning false which will stop execute the generated code.

In user class you can inject code in Insert method by attach your delegate handler in Initialize method.  You can also use Anonymous Method as another option.  Here is how you'll pass parent's id in user class:
        protected override void Initialize()
        {
            executeInsertDelegate = new predicateEx<SqlConnection, RootObject>(child_ExecuteInsert);
        }
        private bool child_ExecuteInsert(SqlConnection cn, RootObject parent)
        {
            _parentID = parent.ParentID;
            return true;
        }
or using Anonymous Method as follow:
        protected override void Initialize()
        {
            executeInsertDelegate = delegate(SqlConnection cn, RootObjec parent)
                                                {
                                                     _parentID = parent.ParentID;
                                                     return true;
                                                 };
        }

Hope my explanation helps you.
Ricky Supit

Copyright (c) Marimer LLC