2016-08-11 13:33 GMT+01:00 mwpowellhtx <mwpowell...@gmail.com>:

>
>
> On Thursday, August 11, 2016 at 8:22:07 AM UTC-4, Oskar Berggren wrote:
>>
>>
>>
>> 2016-08-11 12:33 GMT+01:00 mwpowellhtx <mwpow...@gmail.com>:
>>
>>>
>>>
>>> On Thursday, August 11, 2016 at 7:23:35 AM UTC-4, Rasmoo wrote:
>>>>
>>>> That's exactly Oskar's trick: You call the proxy, into the proxied
>>>> object and get it to cast itself.
>>>>
>>>
>>> No, that's not what Oskar wrote, one the one hand; see below:
>>>
>>> public TCastTarget As<TCastTarget>()
>>> {
>>>     return (TCastTarget)this;
>>> }
>>>
>>> This is not any different than what I attempted in the LINQ statement.
>>>
>>
>> It is in fact completely different. It is applying the cast to an
>> entirely different object.
>>
>
> How so? Watch what I did there.
>
> cup.Juice is a type of Juice, correct?
>


In this line you are attempting to cast the juiceProxy, which as expected
won't work:

> So I want ((AppleJuice) cup.Juice). With me so far?
>


But here, you need to take a moment to ponder which object the "this"
pointer *really* points to:

> Adding Juice.As<TJuice>() { return (TJuice) this; } is no different than
> doing the cast external to the instance.
>

Hint: It is NOT the proxy instance.

In memory you will have
    proxyInstance [points to]-> realInstance  (realInstance present _after_
it's been required for the first time)

And the call path will be something like this:
    proxyInstance.As<ConcreteType>() [calls]->
realInstance.As<ConcreteType>() { so when code here runs, "this" is
realInstance, not proxyInstance }


So as I said, the cast is being applied to a completely different object,
compared to when you apply the cast "externally". And that is a very
important difference, because it will actually work.



>
>
>> On the other hand, introducing an "UnproxiedObject" virtual property is
>>> too much. I want to keep the model itself as clean as possible without
>>> inverting proxy dependency inversions more than is necessary.
>>>
>>
>> It is possible to provide both the As<T>() and "Unproxy()" methods as
>> extension methods instead of putting them in each class. The difference is
>> that the body of the method then need to explicitly check if the object is
>> a proxy and ask NHibernate for the real object before applying the cast.
>>
>
> Well, I wouldn't put them in "each" class, for this contrived example, but
> usually that sort of thing would end up in a base class. Still, not very
> "Liskov", injecting DAL concerns in the domain layer.
>

The benefit of having it in the base class is that the implementation is
self-contained in the model, and doesn't depend on NHibernate. It will work
regardless.

But yes, the fact that you need to use a special method instead of the
normal cast syntax is a leak in the ORM abstraction. We must be pragmatic
and apply the As<>() workaround, or try to use a pattern that avoids the
need for the cast.


/Oskar

-- 
You received this message because you are subscribed to the Google Groups 
"Fluent NHibernate" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to fluent-nhibernate+unsubscr...@googlegroups.com.
To post to this group, send email to fluent-nhibernate@googlegroups.com.
Visit this group at https://groups.google.com/group/fluent-nhibernate.
For more options, visit https://groups.google.com/d/optout.

Reply via email to