I'm trying to design an application that can identify COM objects and their properties on any different application. This is my first time attempting to do so, and I'm not sure where to start even. Ideally, it would be made using Delphi XE2, but I'm open to suggestions.
If I have the CLSID, is there any way to "scan" a running application for what objects were based on it? Or, going another way, is there a better way to list/find active objects in any running application?
Any help is deeply appreciated, as well as any directions towards good documentation on the subject.
Edit: The issue is actually finding out the COM objects in any other application, listing properties and whatever else I need has already been answered in other questions.
There is no way to scan for running COM objects. As soon as they are instantiated - they are just pieces of memory referenced by something else (member interface pointer variables etc).
Sometimes objects are put on Running Objects Table (ROT) and you can retrieve them from there, as already suggested in comments. This attributes for, let's say, <1% of COM object instances, but maybe you are lucky enough to chase for exactly those.
The only way I can think of is hook COM object instantiation in so that you intercept creation and then be able to track your own list of existing instances. This is not an easy way though too (and also it is most likely to be unsafe).
To achieve this you need to either register your class object in the context of running process for the CLSID of your interest and have your class factory receive the instantiation calls. Or, hook CoCreateInstance API, such as with Detours.
Once you are hooking instantiation you have pointers at the moment of object creation and you again need to do something with them. You would want to forward those instantiation calls to the original API, then to track life time of the instances - if you put an extra reference to the object you are likely to alter the original behavior of the application. Otherwise, you have no control to intercept COM object release. Sometimes the COM classes can be created aggregated and you can more or less cleanly embed the original instance in your COM object.
All in all, in general the task does not seem feasible to implement. Having specific CLSID of interest, with a certain luck and quite some effort you might be successful in doing this though.
Related
It seems to satisfy the three requirements here: On Design Patterns: When to use the Singleton?
I need it to exist only once.
I need to access it from all over the source base.
It handles concurrent access, i.e. Locks for writes, but can handle concurrent reads.
Hi all,
I've been reading a lot of no doubt intelligent educated and wise gems of advice that Singletons are 'Evil' and singletons are anti patterns or just plain bad news.
With the argument that logging makes sense but not much else.
Just interested to know if the case of essentially a persistent data store context makes sense for a singleton, i.e. Reading/Writing from disk to memory and referencing an object graph.
And if not, how do people normally tackle this issue, I don't currently have any problem with it, I know it's created only once, it's fast and the accessor logic is in one place. Meaning it takes me one line of code to do anything data model related.
Which leaves the only argument that it's bad for testing, in that it's a hard coded production implementation to data, but couldn't I just write a method swizzle through a category or in the test code to create the test version of the singleton?
And the final argument from DI testers, is that it is a hard coded implementation, rather than simply an interface to something, which I do get but I don't really have a major drive to use a DI framework given that I can use protocols for implementation, and use separate init methods for setting up an objects state in testing. There's only ever going to be two types of state for the singleton, or realistically one type...production.
Making it (in my opinion) much easier to read and faster to develop.
Change my view SO?
Yup, for some singletons are Evil. For the new developers who has little MRC knowledge and more ARC it sounds scary because they need to mess with memory,volatile,synchronize etc.
However it is not against to use them, they indeed has their own purpose to use with some are below.
when sharing large data models like arrays and dictionaries etc between multiple screens (VC's) we can't prefer storing them in UserDefaults (because userdefaults is permanent storage and storing such large entries make app start lazily) instead singletons are best since they stay only current app context and restarting app creates new one.
when we need a stable db connection to be accessible allover the app without messing up with connecting and closing in every business classes we can go for it.
when we wanted an ability to app for theming itself dynamically we would need to create a singleton class which holds all the color,image instances etc. and use that instance in application VC/Views etc so no code duplication and re-processing theme occurs in all places.
You dont have to change your view but tweak it a bit to get some positive intention towards singletons.
Hoping this clears it out, thanks
I have become a great fan of the powerful type system in F# and how it allows you to create some very tight restraints on your domain models (for those interested, see this). I have also become a great fan of RavenDB and how it makes database work very simple in most of the cases I run into. However, there seems to be issues getting the two to play nicely together - at least if you insist on immutable types.
As long as you don't ever have to update your entities, all you need to do is make the id property mutable. While I'm certainly not happy that this is necessary, I can live with it. However, it seems that change tracking is handled in such a way that you must mutate the original object retrieved from the database and it is not possible to attach a new object to the database to represent an updated version of an existing entity. It does seem to be possible to do what I want using the patching API, but the documentation clearly warns against this type of general usage.
Am I missing a part of the RavenDB API that will let me do this without too much fuss or must I abandon the idea of immutable domain models (or perhaps make a feature request for it)?
The problem with immutable in that scenario is that you are actually dealing with mutable data.
The document is being mutated. The fact that you don't mutate it in user space is of little matter here.
What you can do is wrap calls to Advanced.Evict & Store in a StoreUpdated or something like that extension method. But I would call into question the usage of immutable data to represent mutable state.
A global is a piece of data that is accessible in every context by name.
You may heard that "there is an exception to each rule".
I have been programming for several years, and before there was this "hip" of singletons, I started using global variables in my programs.
But, eventually, the programs switched to handle most variables as local, wheter classes fields, or methods fields.
It just came naturally, and it seems that a lot of developers, actually came to the same conclusion, before, after, and the same time, than me ;-)
In most O.O. programming languages, the program itself, is considered an object, and therefore a singleton.
Sometimes, several required global variables, wheter objects or non objects fields, can be encapsulated as a singleton.
Singleton as any other "better practice" or "design pattern", should be used wisely,
learn when & why are useful, and when not to apply.
Cheers.
I think the general idea is that there is not really "global" data. You may consider a program's user information (name, password, hair color) to be global, and in practice it may be. But it is conceivable (maybe using sockets) that other users might become active in the same session. You need a class (User) for this information and, now, several instances of it. And when you need this information, you need the right instance of User at hand. (The correct User object must be passed into the method, or must be available in an instance field; just getting the value from MainClass.userInfo won't work anymore.)
If you originally wrote the program with the idea that there might be multiple users and so far it's never been enhanced to handle them, your User class instance is a singleton and, in a sense, a "global" object as well. But your code will be more intelligible, and in the rare event multiple users are needed, easily upgradable.
I'm looking for a way to control all business objects I create in my applications written in Delphi.
As an article on Embarcadero's EDN (http://edn.embarcadero.com/article/28217) states, there are basically three ways to do this. I'm mostly interested in the last one, using interfaces. That way, when the business object is no longer being referenced anywhere in the application, it will be dispose of memory wise (I'll get back on this part later).
When creating a new business object, it would be wise to ask that new object manager whether I already fetched it earlier in the program, thus avoid the need to refetch it from the database. I already have the business object in memory, so why not use that one? Thus I'll need the list of available objects in memory to be searchable (fast).
The provided code there uses an "array of TObject" to store the collected objects, which doesn't make it very performant concerning searches through the list of objects once you get to a certain amount. I would have to change that to either TObjectList or some sort of binary searchable tree. What would be the best choice here? I already found some useful code (I think) at http://www.ibrtses.com/delphi/binarytree.html. Didn't JCL have stuff on binary trees?
How would I handle "business objects" and "lists of business objects" in that tree? Would a business object, being part of a list be referenced twice in the tree?
Concerning the disposing of an object: I also want to set some sort of TTL (time to life) to that business object, forcing a refetch after an certain amount of time.
Should the reference counter fall to 0, I still want to keep the object there for a certain amount of time, should the program still want it within the TTL. That means I'll need sort sort of threaded monitor looping the object list (or tree) to watch for to-be-deleted objects.
I also came across the Boehm Garbage Collector DLL (http://codecentral.embarcadero.com/Download.aspx?id=21646).
So in short, would it be wise to base my "object manager" on the source code provided in the EDN article? What kind of list would I want to store my objects in? How should I handle list of objects in my list? And should I still keep my object in memory for a while and have it dispose of by a threaded monitor?
Am I correct in my reasoning? Any suggestions, ideas or remarks before I start coding? Maybe some new ideas to incorporate into my code?
Btw, I'd be happy to share the result, for others to benefit, once some brilliant minds gave it a thought.
Thnx.
If you are using Interfaces for reference counting, and then stick those in a collection of some sort, then you will always have a reference to them. If your objective is "garbage collection" then you only need one or the other, but you can certainly use both if necessary.
What it sounds like you really want is a business object cache. For that you will want to use one of the new generic TDictionary collections. What you might want to do is have a TDictionary of TDictionary collections, one TDictionary for each of your object types. You could key your main TDictionary on an enumeration, or maybe even on the type of the object itself (I haven't tried that, but it might work.) If you are using GUIDs for your unique identifiers then you can put them all in a single TDictionary.
Implement each of your business objects with an interface. You don't need to use Smart Pointers since you are designing your business objects and can descend them from TInterfacedObject. Then only reference it by its interface, so it can be reference counted.
If you want to expire your cache then you will need to have some sort of timestamp on your objects that gets updated each time an object is retrieved from the cache. Then when the cache gets over some specific size you can prune everything older then a certain timestamp. Of course that requires walking the entire cache to do that.
Since you are combining interfaces and a collection then if you have a reference to an object (via its interface), and it gets pruned during cache cleanup, then the object will remain alive until the reference goes away. This provides you an additional safety. Of course if you are still using the reference, then that means you kept the reference for a long time without retrieving it from the cache. In that case you may want to update the timestamp when you read or write to the properties too . . . A lot of that depends on how you will be using the business objects.
As far as refetching, you only want to do that if an object is retrieved from the cache that is older then the refetch limit. That way if it gets pruned before you use it again you are not wasting database trips.
You might consider just having a last modified time in each table. Then when you get an object from the cache you just check the time in memory against the time in the database. If the object has been changed since it was last retrieved, you can update it.
I would limit updating objects only to when they are being retrieved from the cache. That way you are less likely to modify the object while it is use. If you are in the middle of reading data from an object while it changes that can produce some really odd behavior. There are a few ways to handle that, depending on how you use things.
Word of warning about using interfaces, you should not have both object and interfaces references to the same object. Doing so can cause trouble with the reference counting and result in objects being freed while you still have an object reference.
I am sure there will be some feedback on this, so pick what sounds like the best solution for you. . . .
Of course now that I have written all of this I will suggest you look at some sort of business object framework out there. RemObjects has a nice framework, and I am sure there are others.
You might want to start by looking at smart pointers. Barry kelly has an implimentation for D2009.
For your BI objects, I would use a guid as the key field, or an integer that is unique across the database. As you load objects into memory, you could store them in a dictionary using the guid as the key and a container object as the value.
The container object contains the bi object, the ttl etc.
Before loading an object, check the dictionary to see if it is already there. If it is there, check the ttl and use it, or reload and store it.
For very fast "by name" lookup in your container object, I suggest you look not to trees, but to hash tables. The EZ-DSL (Easy Data Structures) library for Delphi includes the EHash.pas unit, which I use for my hashing containers. If you are interested in that, I will forward it to you.
I tend to think of "lifetime" oriented "containers" that delete all the objects they own when they close down.
I also think that you might consider making the objects themselves count their "usefulness", by having a "FLastUsed:Cardinal" data field. You can assign FLastUsed := GetTickCount and then have the system basically obey limits that you set up, maximum memory or instances to be actively used and how old an object should be (not used at all in X milliseconds) before it gets "demoted" to level 2, level 3, etc.
I am thinking that for Business Objects, you have a memory cost (keep it around when it could be really only a cache), and a coherency (flush my changes to the database before you can destroy me) constraint that makes traditional "garbage collection" ideas necessary, but not sufficient, for the whole problem of business object lifetime management.
For a higher level point of view, I recommend two books: "Patterns of Enterprise Application Architecture" by Martin Fowler and Eric Evans book about Domain-Driven Design, "Domain-Driven Design: Tackling Complexity in the Heart of Software" (http://dddcommunity.org/books#DDD). Martin Fowler explains all patterns for object management for business applications, including object repositories and different object / database mapping strategies. Eric Evans book "...provides a broad framework for making design decisions...".
There are aleady some (open source) O/R mapper libraries for Delphi with active community, maybe their source code also can provide some technical guidelines.
You are looking for a way to build a container that can store business objects and able to find already instanciated ones a runtime ?
Maybe you could give a look at http://www.danieleteti.it/?p=199 (Inversion of Control and Dependency Injection patterns.)
One of the biggest issues currently holding me back from diving full steam into unit testing is that a really large percentage of the code I write is heavily dependent on third-party COM objects from different sources that also tend to interact with each other (I'm writing add-ins for Microsoft Office using several helper libraries if you need to know).
I know I should probably use mock objects but how exactly would I go about that in this case? I can see that it's relatively easy when I just have to pass a reference to an already existing object but some of my routines instantiate external COM objects themselves and then sometimes pass them on to some other external COM-object from yet a different library.
What is the best-practice approach here? Should I have my testing code temporarily change the COM registration information in the registry so the tested code will instantiate one of my mock objects instead? Should I inject modified type library units? What other approaches are there?
I would be especially grateful for examples or tools for Delphi but would be just as happy with more general advice and higher-level explanations just as well.
Thanks,
Oliver
The traditional approach says that your client code should use a wrapper, which is responsible for instantiating the COM object. This wrapper can then be easily mocked.
Because you've got parts of your code instantiating the COM objects directly, this doesn't really fit. If you can change that code, you could use the factory pattern: they use the factory to create the COM object. You can mock the factory to return alternative objects.
Whether the object is accessed via a wrapper or via the original COM interface is up to you. If you choose to mock the COM interface, remember to instrument IUnknown::QueryInterface in your mock, so you know that you've mocked all of the interfaces, particularly if the object is then passed to some other COM object.
Alternatively, check out the CoTreateAsClass method. I've never used it, but it might do what you need.
It comes down to 'designing for testability'. Ideally, you should not instantiate those COM objects directly but should access them through a layer of indirection that can be replaced by a mock object.
Now, COM itself does provide a level of indirection and you could provide a mock object that provided a substitute for the real one but I suspect it would be a pain to create and I doubt if you'd get much help from an existing mocking framework.
I would write a thin wrapper class around your third party COM object, which has the ability to load a mock object rather than the actual COM object in the unit testing situation. I normally do this by having a second constructor that I call passing in the mock object. The normal constructor would have just loaded the COM object as normal.
The wikipedia article has a good introduction to the subject
Wikipedia artible