It's really easy.  I just pulled out an old ActiveRecord app and threw
an interceptor together in about 2 minutes:

public class MyInterceptor : NHibernate.EmptyInterceptor
{
        private static readonly MyInterceptor instance = new MyInterceptor();

        public static MyInterceptor Instance
        {
                get { return instance; }
        }

        public override bool OnLoad(object entity, object id, object[] state,
string[] propertyNames, NHibernate.Type.IType[] types)
        {
                return base.OnLoad(entity, id, state, propertyNames, types);

                // now do your custom code if "entity" is the particular
ActiveRecord object you're
                // looking to work on
        }
}

And I told ActiveRecord to use this one during my app initialization
with this line of code:

Castle.ActiveRecord.Framework.InterceptorFactory.Create = (() =>
MyInterceptor.Instance);

---
Patrick Steele
http://weblogs.asp.net/psteele



On Wed, Dec 16, 2009 at 11:18 PM, Paul de Wit <[email protected]> wrote:
> Thanks Patrick
> I'll have to think about that one, expired is a Job status and therefore an
> enum. I may have to go down the interceptor route :)
>
> On Thu, Dec 17, 2009 at 3:00 PM, Patrick Steele <[email protected]>
> wrote:
>>
>> I was thinking using a nullable bool similar to this:
>>
>> public class Job : ActiveRecordBase<Job>
>> {
>>    private bool? expired;
>>
>>    public bool Expired
>>    {
>>        get
>>        {
>>            if( expired == null )
>>            {
>>                // determine expired state and set value here
>>            }
>>            return expired.Value;
>>        }
>>        set
>>        {
>>            expired = value;
>>        }
>>    }
>> }
>>
>> So the first time the Expired property is accessed, your logic to
>> determine if its expired can be executed.
>>
>> ---
>> Patrick Steele
>> http://weblogs.asp.net/psteele
>>
>>
>>
>> On Wed, Dec 16, 2009 at 10:40 PM, Paul de Wit <[email protected]> wrote:
>> > Thanks for the time spent on this I really appreciate it :)
>> > I'm fairly new to activerecord, you said
>> > "lazily decide it's state the first time it's called instead of doing at
>> > entity load time?"
>> > I'm not sure how you do this I thought this is actually what I was
>> > trying to
>> > do.....
>> > The "Job" object is being referenced at many different places in the web
>> > application so I don't want to put checks all throughout the web app to
>> > test
>> > for expiry. I need some centralized method (like OnLoad) to check for
>> > this
>> > expiry. If I can "lazily" decide its state somehow the first time its
>> > called
>> > I would love to know how to do this!
>> >
>> > On Thu, Dec 17, 2009 at 2:31 PM, Patrick Steele
>> > <[email protected]>
>> > wrote:
>> >>
>> >> Interesting.  I dug through the ActiveRecord code and the OnLoad
>> >> method ties into NHibernate's IInterceptor.OnLoad.  This method is
>> >> called *before* the data returned from the database is used to
>> >> populate the entity.  In fact, the method comment states:
>> >>
>> >> /// <summary>
>> >> /// Hook to transform the read data
>> >> /// from the database before populating
>> >> /// the object instance
>> >> /// </summary>
>> >>
>> >> So that is why your entity is empty during OnLoad.  However, what I
>> >> found interesting is that NHibernate's IInterceptor.OnLoad is passed
>> >> the data read in from the database giving you a chance to change it
>> >> before it is used to populate the entity (which sounds like exactly
>> >> what you want).  But that information is not relayed down into the
>> >> ActiveRecordBase OnLoad method.  Not sure why that is.
>> >>
>> >> So I guess one possible workaround is to create your own IInterceptor
>> >> (or inherit from NHibernate.EmptyInterceptor and override the OnLoad
>> >> functionality like ActiveRecord did).  You could have your expired
>> >> check there.  The InterceptorFactory.Create delegate can be assigned
>> >> to create an instance of your interceptor instead of the default
>> >> ActiveRecord one.
>> >>
>> >> And this is all based on me skimming over the code for about 15-20
>> >> minutes, so take it with a grain of salt.  There may be an easier way
>> >> to do this.  For example, if you have an "Expired" property, could you
>> >> lazily decide it's state the first time it's called instead of doing
>> >> it at entity load time?
>> >>
>> >> ---
>> >> Patrick Steele
>> >> http://weblogs.asp.net/psteele
>> >>
>> >>
>> >>
>> >> On Wed, Dec 16, 2009 at 8:32 PM, Paul de Wit <[email protected]> wrote:
>> >> > Anyone have any thoughts on this problem?
>> >> >
>> >> > On Thu, Dec 17, 2009 at 1:43 AM, Paul de Wit <[email protected]>
>> >> > wrote:
>> >> >>
>> >> >> Hey
>> >> >> Thanks for the quick reply it inherits from "ActiveRecordBase<Job>"
>> >> >> On Thu, Dec 17, 2009 at 12:59 AM, Wayne Douglas
>> >> >> <[email protected]> wrote:
>> >> >>>
>> >> >>> what does this class inherit from that provides the OnLoad method
>> >> >>> you're
>> >> >>> overriding?
>> >> >>> need some more info.
>> >> >>> w://
>> >> >>>
>> >> >>> On Wed, Dec 16, 2009 at 1:27 PM, paulddw <[email protected]> wrote:
>> >> >>>>
>> >> >>>> This method is inside a class called "Job". Everytime a job is
>> >> >>>> loaded
>> >> >>>> I would like to check the status and set to expired if required.
>> >> >>>> However the properties on the instance are all null. How do I
>> >> >>>> populate
>> >> >>>> the instance??
>> >> >>>>
>> >> >>>> protected override void OnLoad(object id)
>> >> >>>> {
>> >> >>>>     base.OnLoad(id);
>> >> >>>>     //manipulate data here
>> >> >>>>
>> >> >>>> }

--

You received this message because you are subscribed to the Google Groups 
"Castle Project Users" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/castle-project-users?hl=en.


Reply via email to