How do I consume Classes i have stored in Application? - vbscript

I have defined a class like this:
Class Foo
Public SomePublicProperty
Public Function init(p_somePublicProperty)
set init = Me
SomePublicProperty= p_somePublicProperty
End Function
End Class
And then consumed that in my global.asa Application_OnStart lke this:
Dim fooInstance
Set fooInstance = New Foo.init("Some data")
fooArray = Array(fooInstance)
Application("fooArray") = fooArray
Which works fine but when i get the value back out of the application store on another page i can't get at the property...
fooArray = Application("fooArray")
fooArray(0).SomePublicProperty 'This line returns an error - Object doesn't support this property or method
I have tried putting the class definition into the second page, but it doesn't help.
What have I missed?
I have just found this question. Am I right in assuming the same rule re serialization applies equally to the Application object? and so i shouldn't try and do this?

Unfortunately you can't do this, here is a the best explanation I could find as to why;
From Can I store VBScript class objects in a Session variable?
This is because VBS classes are NOT true classes. They are really just in-memory collections of info, and there is no way to guarantee (for example) that an instance that is stored in one page will even come close to matching the class definition in another page.
This is not the same as using Server.CreateObject() COM objects which can be stored and retrieved from both the Application and Session objects.
You have a couple of options;
Serialise the object yourself, in a structured string then use this to de-serialise the object when needed.
Create a COM wrapper for your VBScript class and stop using Class statement altogether. As COM objects can be stored in Application and Session objects this should work as long as the COM class is single threaded.
Convert your class into an Array and use this instead.
Useful Links
Application Object (IIS)
Setting the Scope of COM Objects in ASP Pages - Giving an Object Application Scope

Related

How to check where a who calls this method?

I have a custom method in an ABAP class.
I used the 'Where used' tool to show where the class is called from but, as it turns out, it's called from somewhere else I didn't expect.
So what's the best way of showing a complete list of everything that calls the method?
Due to the wonders of object-oriented programming, an instance of a class can hide behind a reference to one of its base classes or interfaces it implements. For example:
DATA foo TYPE REF TO z_my_interface.
CREATE OBJECT foo TYPE z_my_class.
" lots of more code
foo->bar( ).
You can not find this reference to z_my_class->foo with its "Where Used" list, because at that code location foo could also be a reference to an instance of any other class which implements z_my_interface. But you might be able to find this if you don't just look at the where-used list of the method but at the where-used list of the whole class or the interface / base class which declares the method.
And then there are evil dynamic programming tricks like this which determine methods and classes at runtime:
DATA foo TYPE REF TO object.
CONSTANTS: classname TYPE string VALUE 'Z_MY_CLASS',
methodname TYPE string VALUE 'BAR'.
CREATE OBJECT foo TYPE (classname).
CALL METHOD foo->(methodname).
There is no chance to find this with the where-used tool. But if the class- and/or method name does actually appear in the code (it might not, for example if they are read from a customizing table) then you can use the report RS_ABAP_SOURCE_SCAN. This handy little tool allows you to select a set of ABAP programs and search for strings (and even regular expressions) within their sourcecodes.
However, if you know the method gets called when you do something specific as a user and just want to know where, then it can be easier to just set a debugger breakpoint in the method, run into it and check the call stack.
Sorted using the code_scanner transaction.

Filenet Change Document Class

I'm trying to change class for a given document and below is the code that I used
Document p8Document = Factory.Document.getInstance(p8ObjectStore,
oldDocumentClassName, new Id(documentId));
p8Document.changeClass(newDocClassName);
p8Document.save(RefreshMode.REFRESH);
Upon executing the code, I can see that document class is being changed successfully. Now the problem is if I run the code again for the same guid, the below line fetches the document again with the old document class name.
Document p8Document = Factory.Document.getInstance(p8ObjectStore,
oldDocumentClassName, new Id(documentId));
By using getInstance, you are not asking the server to verify the existence of the object. Use fetchInstance instead.
From Instantiating Objects
The getInstance methods are used to instantiate an object that references a server object that is assumed to already exist. The existence of the object is not verified on the Content Engine server, and no round trip to the server is made until you perform a function on the object
getInstance is a way that you can setup an object while avoiding a trip to the CE server.
The fetchInstance methods instantiate an object by first making a round-trip to the Content Engine server and retrieving ("fetching") property values.
fetchInstance actually will retrieve the object from the CE server.

QTP Descriptive Programmuing -Loading the objects created through function

I have 10 different test cases .I want to create different objects of SwfEdit, SwfButton etc just once say in function and then use those in different actions in QTP.
I tried creating a function and linked it to a test case,however it did not work.
So I am not sure what could be correct way to link all these objects across all the test cases.
If you insist on creating your objects in code instead of using the object repository, you'll need to store those objects in some type of global variable. A basic example might be for a function library:
' Declare your global variable to hold the object
Public MyObject
' Create your object from a function
Public Sub InitializeGlobalObject()
' Use Descriptive Programing to create your object
Set MyObject = Window("title:=something").Button("index:=0")
End Sub
This will allow you to create the object once and then refer to it by the variable
' Click the button
MyObject.Click
You may run into issues caching an object like this because it will tend to hold on to the last screen object that it matches, whereas the object repository will refresh the screen object each time you call it. You may need to call the 'Refresh' method on your object before you use it for the first time after it is displayed on the screen.
You should use object repository to add objects first if you are not intending to use descriptive language.
You should spy on each object and then add it.

Properly Refactoring to avoid a Circular Dependency

I am having a problem with a circular dependency. Similar question have been asked and I have read a lot of answers. Most deal with a work-around but I would like to refactor so what I have it correct and I would like some input on where I have gone wrong. I can change what I am doing but not the entire project architecture.
I am using VB.Net in Visual Studio 2012.
I have two class libraries:
DataLayer for accessing the database.
DataObject which contains classes that represents my business objects.
My Presentation Layer calls methods in the DataLayer which returns objects from the DataObject class library.
(I have simplified somewhat – I actually have a controller layer but it needs references to the two class libraries above. This is an existing architecture that is from before my time.)
In the DataObject class library I have an abstract class that represents a file. It has properties such as filename, userID, etc. It also has a method, GetFile(), that I code in the derived classes because there are different ways of getting the file. A DataLayer method returns a collection of these file objects, but I don't want to get the actual file until it's needed.
So far, I have a derived class that calls a webService (using properties from the baseClass) and a derived class that accesses the fileSystem. Both return a byte array representing the file. The calling class does not need to know how the file is retrieved.
Now I have a new requirement to build the file on the fly using data from the database. I can get all the data I need using the properties in the base class.
My issue is that my GetFile() method will need to access my DataLayer class library to pull data from the database which causes a circular dependency. The DataLayer class library has a reference to DataObject since that is what it returns. But now I need to call the DataLayer from a class in DataObjects.
I could call the DataLayer from presentation and pass the result to
my DataObject’s GetFile() method, but then my presentation layer
needs to do something special for this derived class. My goal is
that the derived class handles GetFile without presentation knowing
about the implementation.
I could create a new class library for this DataLayer code but I
don't like a special case.
I could access the DB directly in the DataObject class but that
circumvents the layered architecture.
I can’t change our architecture, but I can change my approach.
Any opinions?
I think I have the answer.
In my concrete class, when I am loading the data initially (in the DataLayer), I will get all the data I need to create the file. I'll store it in a new property in my concrete class which my GetFile() method will use to build the file.
This has a little more overhead - I make DB calls and put all this data in memory when it may not be needed. I'll give it a try and see how performance is.
Any critiques of this approach?

OO Design: Multiple persistance design for a ruby class

I am designing a class for log entries of my mail server. I have parsed the log entries and created the class hierarchy. Now I need to save the in memory representation to the disk. I need to save it to multiple destinations like mysql and disk files. I am at a loss to find out the proper way to design the persistence mechanism. The challenges are:
How to pass persistence
initialization information like
filename, db connection parameters
passed to them. The options I can
think of are all ugly for eg:
1.1 Constructor: it becomes ugly as I
add more persistence.
1.2 Method: Object.mysql_params(" "),
again butt ugly
"Correct" method name to call each
persistance mechanism: eg:
Object.save_mysql, Object.save_file,
or Object.save (mysql) and
Object.save(file)
I am sure there is some pattern to solve this particular problem. I am using ruby as my language, with out any rails, ie pure ruby code. Any clue is much welcome.
raj
Personally I'd break things out a bit - the object representing a log entry really shouldn't be worrying about how it should save it, so I'd probably create a MySQLObjectStore, and FileObjectStore, which you can configure separately, and gets passed the object to save. You could give your Object class a class variable which contains the store type, to be called on save.
class Object
cattr_accessor :store
def save
##store.save(self)
end
end
class MySQLObjectStore
def initialize(connection_string)
# Connect to DB etc...
end
def save(obj)
# Write to database
end
end
store = MySQLObjectStore.new("user:password#localhost/database")
Object.store = store
obj = Object.new(foo)
obj.save
Unless I completely misunstood your question, I would recommend using the Strategy pattern. Instead of having this one class try to write to all of those different sources, delegate that responsibility to another class. Have a bunch of LogWriter classes, each one with the responsibility of persiting the object to a particular data store. So you might have a MySqlLogWriter, FileLogWriter, etc.
Each one of these objects can be instantiated on their own and then the persitence object can be passed to it:
lw = FileLogWriter.new "log_file.txt"
lw.Write(log)
You really should separate your concerns here. The message and the way the message is saved are two separate things. In fact, in many cases, it would also be more efficient not to open a new mysql connection or new file pointer for every message.
I would create a Saver class, extended by FileSaver and MysqlSaver, each of which have a save method, which is passed your message. The saver is responsible for pulling out the parts of the message that apply and saving them to the medium it's responsible for.

Resources