Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

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

Posted

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?

  • Leaders
Posted
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?
[sIGPIC]e[/sIGPIC]
Posted

First thank u for replying.

Ok I'll try to be more explicit and more direct giving an example.

 

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

 

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 :

 

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

  • Leaders
Posted

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:

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:

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.

[sIGPIC]e[/sIGPIC]
Posted

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

  • Leaders
Posted
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.
[sIGPIC]e[/sIGPIC]
Posted

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)

  • Leaders
Posted

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.

[sIGPIC]e[/sIGPIC]
Posted

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.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...