Intercept property getter call ?

docflied

Newcomer
Joined
Nov 28, 2009
Hello people, nice forum and nice contents.

I am new to .net and hope to get some help in order to do this :
Saying we havec a ClassA within a method called DoWorkWhenPropertyGetterIsCalled.

A ClassB inherits form ClassA and define lets say two properties ProBA binded to a private mA field and PropB binded to a private mB field.

What's the best way (if exists) to ensure calling DoWorkWhenPropertyGetterIsCalled each time objCallB.PropX is called?
Another ClassC subclass of ClassA also may define ProPA to PropZ and I need the method to be called automatically each time a property getter is defined.

Well hope I was clear enough... Thank u all in advance for ur help
 

docflied

Newcomer
Joined
Nov 28, 2009
Feeling a bit frustrated since no replies or even a road map...
May be my question is stupid since the solution to what I am asking is obvious. In this case please forgive me and bag u to tolerate my ignorance of .net framework.

Searching hard but nothing seems to match. Found something like MultiCast delegate and using reflection to combine a listener on the GetGetMethod.
But dont know hell how I can do this.

What I am trying to do (detecting getter calls) is a step in a more complex need. Actually just before returning result in getter function and if the result is an instance of a particular class in my project (thus it's a prepared object) I'll ask the object to compelte itself (prepared --> loaded) with heavy database exchange.

Any idea please?
 

snarfblam

Ultimate Contributor
Joined
Jun 10, 2003
Location
USA
It's a bit hard to understand what you are after. Are you looking to detect when a property is retrieved from an object and perform some logic before the result is returned? Is it a class you wrote or have access to the code for? And will the logic that occurs be part of the class that the property belongs to, a class that uses said class, or a different class altogether?
 

docflied

Newcomer
Joined
Nov 28, 2009
First thank u for replying.
Ok I'll try to be more explicit and more direct giving an example.

Code:
Class MyBaseClass
...
End Class

Class MySubClassA
  Inherits MyBaseCLass

  Private mFieldA1 As Object
  Private mFieldA2 As Object
  ...
  Private mFieldAn As Object

  Property PropA1 As Object
    Get
      'Need to place code here
      Return mFieldA1
    End Get
    Set(ByVal value As String)
       mFieldA1 = value
    End Set
  End Property
	
  Property PropA2 As Object
    Get
      'Need to place code here
      Return mFieldA2
    End Get
    Set(ByVal value As String)
      mFieldA2 = value
    End Set
  End Property
	
  ...
	
  Property PropAn As Object
    Get
      'Need to place code here
       Return mFieldAn
    End Get
    Set(ByVal value As String)
      mFieldAn = value
    End Set
  End Property
End Class

Another subclass

Code:
Class MySubClassB
  Inherits MyBaseCLass

  Private mFieldB1 As Object
  Private mFieldB2 As Object
  ...
  Private mFieldBm As Object

  Property PropB1 As Object
    Get
      'Need to place code here
      Return mFieldB1
    End Get
    Set(ByVal value As String)
      mFieldB1 = value
    End Set
  End Property
	
  Property PropB2 As Object
    Get
      'Need to place code here
      Return mFieldB2
    End Get
    Set(ByVal value As String)
      mFieldB2 = value
    End Set
  End Property
	
  ...
	
  Property PropBm As Object
    Get
      'Need to place code here
      Return mFieldAm
    End Get
    Set(ByVal value As String)
      mFieldBm = value
    End Set
  End Property
End Class

And so on ... For any subclass MySubClassC, MySubClassD

What I need is to detect (event or delegate or any other solution) each time Prop<X><i>.getter is called and put this code in the base class.
Something like :

Code:
Class MyBaseClass
...

Protected Sub GetterCalledEvent(....)
  'Here I need to got a reference
  'to the mField<X><i> wich will be returned
  'in the getter just after this sub ends.
End Sub

End Class

Really sorry for my first post. Hope I am clear this time.

And to answer your question yes it is exactly what you wrote except that the code when detecting getter caller will be common and placed in the base class so any future subclass (written by someone else) will trigger implicitly the same detection and the same logic.

Thanks in all cases
 

snarfblam

Ultimate Contributor
Joined
Jun 10, 2003
Location
USA
It sounds like you would like to implement some sort of lazy initialization. Assuming that's the case...

When a class defines it's own new member as in your example, the base class can't compel any subclass to do anything. One option would be for the base class to implement a protected member (can only be accessed by subclasses) that your subclasses would be expected to call.

In this case you base class would be something along the following:
Visual Basic:
Public Class CommonBase
    ''' <summary>
    ''' Subclasses should call this method to ensure that the object is
    ''' initialized before using the base class.
    ''' </summary>
    Protected Sub EnsureInitialized()
        'Do stuff
    End Sub
End Class
And a subclass would look like this:
Visual Basic:
Public Class SubclassA
    Inherits CommonBase

    Dim _a As Object
    Public Property A() As Object
        Get
            ' Our lazy initialization, not compulsory
            EnsureInitialized()
            Return _a
        End Get
        Set(ByVal value As Object)
            ' Should something go here?
            _a = value
        End Set
    End Property
End Class


If your code example is any kind of indication of what the actual code will look like, it might be more appropriate to use a whole different approach to access the data/values. I have no idea what the code will do or why, but there are other designs that might suit your needs better.

For example, if these properties are something that could be indexed then the base class could expose a public sealed property that accepts one parameter (the index) and performs the lazy initialization, then calls an overridable protected function that a subclass can override to implement its own logic and return its own value based on the index.

Not knowing anything about your app, I have no idea what, specifically, could work for you.
 

docflied

Newcomer
Joined
Nov 28, 2009
Thank u for ur explanations. I am aware that I gave not enough details and my question is somehow ambigous.
The first solution u indicated that's excatly what I am doing now, thus calling EnsureInitialized in each subclass property getter.

For now it's OK.

The problem will start when other developpers will code new classes subclassing my BaseClass.
I have no guarantee that they will call EnsureInitialized in each property they'll code in this new SubClass. Got it?

That's why my idea (my dream) was to detect in the BaseClass any getter call done using an instance of any futur or existing SubClass coded by anyone.

I am on my way to end an alternative solution, hoping it will work even if I am sure it will imply performance decrease :

Create a method in the base class that use Reflection to discover each property getter. Using DynamicMethod, IL and Emit to inject hooks for each getter and ensure calling the common needed logic.

Reflection is nice, but when I can avoid it I dont hesitate in ordre to not get performance decreasing but sounds like in my case there is no other alternative (at least known alternative)

Thank u again for ur help
 

snarfblam

Ultimate Contributor
Joined
Jun 10, 2003
Location
USA
So... you are injecting code into functions that have yet to be written whose details you know nothing about? Pardon the expression, but that has a very bad "code smell." Based on the little we know it sounds like a monster of a hack to compensate for a glaring problem in your object model.
 

docflied

Newcomer
Joined
Nov 28, 2009
No hacking here man... I've written the whole object model and what I am doing is actually guidance for future inheritance of future classes developped by foreign people.

As I allready said all what I want is a "good" way (cause I agree that code injection smells bad) to detect any property getter call and do something before returning the result of this getter.

The aim is to prepare objects without calling resource consuming processes.
And only when thoses objects are "GETTED" and only if the are "GETTED" then i'll Load them.

Let's say u have an object "CHILD" that read itself from database after u assigned some of its keys related properties.
Then let's say u have an object "PARENT" onwning the "CHILD" object as a private member and exposing it with a property "getChild"

When the parent is created and loaded, the child is supposed to be created and loaded also.

Instead of doing that, I am creating and preparing (not loading) the child object within the parent creation process.

And only when "someone" calls Parent.geChild and just before returning the associated private member I aim to really load the object.

I really want to copy paste my code but I got discolsure obligations and code is classified (even if I sware there is no reason to)
 

snarfblam

Ultimate Contributor
Joined
Jun 10, 2003
Location
USA
Perhaps a more "dynamic" method would be in order then. Rather than creating and compiling various classes and properties, some sort of collection class to hold the values would be more appropriate. The collection can contain other collections to accomodate arbitrary data structures, and since access to values would all be through a small number of functions it would be easy to implement lazy initialization.

Sometimes using a language's object-oriented constructs isn't the best way to go. You are trying to use the DotNet type system in a way that it just isn't meant to be used.

FYI, when I said you were using a "hack", I didn't mean that what you were doing is morally suspect. I meant "hack" as in a less-than-ideal shortcut or workaround to make something work.

Also, (I know you may not be able to divulge many details, but) just what are these properties doing that the base class won't know when it needs to initialize? Are these objects being deserialized from a direct representation in the database? Usually a subclass can implement it's own properties and the base class won't need to lazy-initialize until the subclass accesses a member on the base class. That works fine except in the rare situation where a base class is responsible for initializing a subclass in a late-bound manner.

I'm impressed by your determination to make this work the way you would like it to, but I just can't imagine any possible scenario where there isn't an easier way. Do as you'd like (or as your boss would like), of course, but I suggest you (or your boss) reconsider the approach.
 

docflied

Newcomer
Joined
Nov 28, 2009
Oh I am not an obstinate guy and agree almost your analyze of the problem.
I am not expert in .net but got a solid experience in OOP (Java) and cant just imagine that a cleaner maner doesn't exist.

As u said, my boss !! that's it. An time is missing as usually.

Today my problem is solved by properties inspection and injection of a common and central method. Now I am on security matters to avoid other doing what I've done :)

In all cases thank u all for ur advices, especially marble
Read u soon, when I'll got another issue.
 
Top Bottom