Yes basically you are right but I just find it to be a lot of plumbing if I in my DAO (Reposoitory) need to go through all the objects returned from NHibernate and replace those with proxies where I need my custom lazy loading.

But I looked further into why my custom ReflectionOptimizer was not called for components, bascially because it's interesting to lean from reading other peoples code and not because I expected to find a quick solution, but I actually found something that might be a bug or it might just be left like that intentionally. It should be noted that we are currently using NH 2.1.0 on our project.

In PocoComponentTuplizer.BuildInstantiator there are the following code:

            if (optimizer == null)
            {
                return new PocoInstantiator(component, null);
            }
            else
            {
return new PocoInstantiator(component, optimizer.InstantiationOptimizer);
            }

My problem was that even though I had enabled the optimizer the optimizer was always null here. Looking further I could see that the optimizer is set in the constructor of PocoComponentTuplizer

if (hasCustomAccessors || !Cfg.Environment.UseReflectionOptimizer)
            {
                optimizer = null;
            }
            else
            {
optimizer = Cfg.Environment.BytecodeProvider.GetReflectionOptimizer(componentClass, getters, setters);
            }

However BuildInstantiator is only called from the constructor of the class that PocoComponentTuplizer inherits from: AbstractComponentTuplizer. So basically then BuildInstatiator is called before it's checked if the reflection optimizer should be used. Maybe it's a bug or maybe it's intentionally left like this, but then at least there is code that is obsolete in the BuildInstantiator as it can never be reached.

What I then did was to call BuildInstatiator again in the constructor of PocoComponentTuplizer after setting the optimizer:

instantiator = BuildInstantiator(component);

One line of code extra and then suddenly all of my unit tests for my custom lazy loading became green. :-)


regards Henrik Uffe Jensen

On 5/26/2010 1:20 PM, Fabio Maulo wrote:
NH is not a DAO.
You can use it as a DAO in some cases but NH is not designed to be a DAO.
In your DAO you should load info. from NH and from the other external-service and then populate your object.

There are others ways as ObjectsFactory, Tuplizer, and/or your special ProxyFactoryFactory but... as said, it is the hard way.

On Wed, May 26, 2010 at 6:52 AM, Henrik Uffe Jensen <[email protected] <mailto:[email protected]>> wrote:

             Hi

    In a solution I'm working on I have quite a lot of objects mapped as
    components where only the id is in my local database and other
    properties of the object is stored behind a service boundary (so need
    to make a service call with the id to get the information).

    So I want to implement some custom lazy loading because in the case I
    don't need the other properties than the id on those objects then I
    don't want to make the service call.

    As I'm using Windsor Container anyway in the solution, however so far
    not for my domain objects, then my idea was to create an interceptor
    and then let it react on the getters to load the data from the service
    dynamically. And I then used NHibernates IInterceptor.Instantiate to
    resolve my objects from the container if present and otherwise just
    return null and let NHibernate construct the object.

    And in my initially test this also worked fine. But it turned out now
    that it was only because I was testing my custom lazy loading directly
    on entities mapped as a class not as a component.

    Apparently instantiation of components do not seem to go through
    IInterceptor.Instantiate. Is my observation correct?

    I then tried with a custom Bytecoderprovider as described in this post
    by Fabio:
    http://fabiomaulo.blogspot.com/2008/11/entities-behavior-injection.html

    But again it works fine for entities mapped as classes but components
    seem to be instantiated differently. Is my observation correct again?

    So are there some way to hook into the process of instantiation of the
    components that I have just not found?

    Or is there a completely better way of getting he behavior I'm looking
    for? I'm thinking of skipping my current path completely and then
    looking into custom accessor for the custom lazy loading instead, but
    It's just sad as I was so close on the current path. If just component
    construction went through IInterceptor.Instantiate or CreateInstance
    of the  ReflectionOptimizer then it would have worked.

    regards

    Henrik Uffe Jensen




    --
    You received this message because you are subscribed to the Google
    Groups "nhusers" group.
    To post to this group, send email to [email protected]
    <mailto:[email protected]>.
    To unsubscribe from this group, send email to
    [email protected]
    <mailto:nhusers%[email protected]>.
    For more options, visit this group at
    http://groups.google.com/group/nhusers?hl=en.




--
Fabio Maulo

--
You received this message because you are subscribed to the Google Groups "nhusers" 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/nhusers?hl=en.

--
You received this message because you are subscribed to the Google Groups 
"nhusers" 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/nhusers?hl=en.

Reply via email to