1

Purpose: What I'd like to do is to implement a console for my WinForm application to query certain objects' (i.e which implement an interface) properties at runtime. I'd like to list all instances of some Type, and display all properties of a selected instance. Yeah.

After reading the question "How do I get all instances of all loaded types that implement a given interface?", I'm ascertained that this cannot be done in a reasonable way (i.e without walking the heap?!) and evaluating a container approach, such that instances will register themselves to the container and unregister from it on destruction, etc, but I'm not satisfied with the alternatives I've got:

  • Deriving all the classes from a base class that handles container-work: I wouldn't prefer inheritance.
  • Implementing a container service and constructor-injecting it: The best one I've come up with, but I'm seeking a more transparent solution.

Question: When using a container approach, is there a better (more transparent, minimum lock-in) pattern?

Note: Alternative ways for the same purpose are also welcome.

Community
  • 1
  • 1
henginy
  • 2,041
  • 1
  • 16
  • 27

2 Answers2

0

If inheritance is not acceptable to you, you can try using a AOP framework like PostSharp to track objects. You can decorate all objects that you want tracked with a suitable attribute and associate that attribute with a postsharp construct.

I have used this to implement undo redo with success.

parapura rajkumar
  • 24,045
  • 1
  • 55
  • 85
0

Having each class handle the container work is the most transparent solution. Having all classes inherit from a base class would be the easiest way to do this, but might get in the way of other things you want to do with inheritance. But there should not be that much code involved, so duplicating it for each class should not be a big problem, and a few static methods somewhere could get rid of almost all of it.

However, I think the better solution would be to add a couple of methods to the interface: Activate (or maybe Initialize) and Deactivate (Dispose?). A class's methods implementing Activate and Deactivate can work as described above or call the container service, as you wish.

You do have to remember to call these methods, but they give you a lot of power. They can handle other initializations that might not work well in the constructor. They allow an individual object to opt out of your container if you find some objects don't need to be there. It also allows it to opt into other other containers you might use in the future. In short, an object of any class is given a lot of freedom to handle its own business within the program structure, and the program can create and manage a lot of complex objects of wildly different classes with a few simple method calls.

RalphChapin
  • 3,108
  • 16
  • 18