docflied Posted November 28, 2009 Posted November 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 Quote
docflied Posted November 28, 2009 Author Posted November 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? Quote
Leaders snarfblam Posted November 28, 2009 Leaders Posted November 28, 2009 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? Quote [sIGPIC]e[/sIGPIC]
docflied Posted November 28, 2009 Author Posted November 28, 2009 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 Quote
Leaders snarfblam Posted November 29, 2009 Leaders Posted November 29, 2009 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. Quote [sIGPIC]e[/sIGPIC]
docflied Posted November 29, 2009 Author Posted November 29, 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 Quote
Administrators PlausiblyDamp Posted November 30, 2009 Administrators Posted November 30, 2009 Out of interest could you give a bit more detail about the scenario you are aiming for? There might be an alternative solution that offers an eassier path. Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
Leaders snarfblam Posted December 1, 2009 Leaders Posted December 1, 2009 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. Quote [sIGPIC]e[/sIGPIC]
docflied Posted December 1, 2009 Author Posted December 1, 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) Quote
Leaders snarfblam Posted December 1, 2009 Leaders Posted December 1, 2009 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. Quote [sIGPIC]e[/sIGPIC]
docflied Posted December 1, 2009 Author Posted December 1, 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. Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.