Saturday, June 25, 2005

[Opf3] Question: How to use Opf3 with more then one storage?

Question
Hello Christian, we are in the process of evaluating OPF here at our company. One issue we are having is a good way to implment OPF for many tables. For example, we might have 10 tables in one database and 5 in another in the same project. We are writing the same basic code to generate an ObjectSet to place use it for a datasource and then to persist each one in it's own try..catch block etc.. Before we begin writing a helper class to manage these things in a more general way, I was wondering if you had any advice or even sample code for a good way to handle this.

Answer
I tried to help a little bit with the blog entries about "Opf using multiple storages" and "Using multiple storages and web-services". Those two entries try to show the main patterns you should respect when working with multiple storages.

Consider a few things when working with multiple storages:

  • A persistent object "lives" in one instance of the ObjectContext. That means that the instance of the ObjectContext, which loaded or saved the persistent object, stores internally the relevant data about that persistent object. It stores the information about the current state of the object (loaded, saved, deleted, etc.) and the concurrency data (if you are using a concurrency manager).
    If you use in your application one instance of the ObjectContext for one storage and another instance for the other storage and you don't serialize the persistent objects you are fine. On serialization the persistent object leaves the AppDomain and the garbage collector removes the no longer instance of the object. The ObjectContext "thinks" then that the object is no longer existing and removes the internal structures.

  • On the other hand if you have a lot different instances of the ObjectContext in your application (you generate them for example on the fly on each operation on the storage) your persistent objects should implement the ISelfContainingObject interface. By implementing this interface the persistent objects manage their state (no longer the instance of the ObjectContext does them for them) by themself.

  • Relations do not work very well if you reference from one persistent object a list or a single persistent object that lies in another storage. Opf3 associates the instances of ObjectHolder, ObjectSetHolder and ObjectListHolder in a persistent object with the ObjectContext used to load or save the persistent object. This means the time you are requesting the related object(s) it uses that ObjectContext to load those objects. If those objects are not found in the storage or you get an exception or it returns an empty list.
    Relations have to be done by hand if you cross-reference storages (at least those relations referencing from one storage to another).



A way to implement your scenario would be creating an ObjectContextFactory that returns an instance of the ObjectContext for one storage and an instance for the other storage. Those instances are created once and returned on each request for an instance of the ObjectContexts.

Attention: An instance of the ObjectContext does not work properly if used by two or more threads! If you need multithreading in your application you should consider to create for each thread an instance of the ObjectContext and use it within that thread. If your persistent objects do not implement the ISelfContainingObject interface you should be careful when passing them from one thread to another.

You can also implement the ISelfContainingObject interface in all your persistent objects. But, when you save a persistent object in one storage that you loaded from another storage you have to reset manually the state of the object, otherwise Opf3 tries to update the persistent object. See "Using multiple storages and web-services".

I hope I could help you. If you have further questions please post them as comments.

0 Comments:

Post a Comment

<< Home