Thursday, June 30, 2005

Today is fish!

There is one day in everybody's life where no photoshop is required to impress people. That day happened to some fishers yesterday.

Wednesday, June 29, 2005

[Opf3] Recommended pattern: ObjectContextFactory

For creating instances of the ObjectContext class in your application I highly recommend to create some factory that creates them for you. A factory is a class that contains one method that returns an initialized instance of a certain class.

An example of such a class is found in the Opf3.Utilities. That class requires creating your own ObjectContextFactory (by inheriting from the current one in Opf3.Utilities) and overriding one method of that base class (the name of the method is CreateObjectContext). In the overriden method you have to create an instance of the ObjectContext and return that instance. The instance of the ObjectContext is retrieved by calling the method "GetObjectContext" (see example).


MyObjectContextFactory fact = // Get the ObjectContextFactory from some static class.
// Get an instance of the ObjectContext.
ObjectContext context = fact.GetObjectContext();

// Get all user from the storage.
ObjectSet<User> os = context.GetObjectSet<User>();


The ObjectContextFactory that comes with the utilities creates a new instance of an ObjectContext for each different thread requesting an ObjectContext. This means that in a multithreaded environment each thread has it's own instance of the ObjectContext. If the thread does no longer exist the instance is removed automatically.

If you need any other behaviour you can use the ObjectContextFactory of the utilities as a template or adopt it to work in your scenario(s).

Final exams approaching

Next week I have my final exams for this term. I need some vacation after that, like a week doing only things I like (coding and relaxing :D).

After my short "vacation" I'm starting to work for Sarix GmbH (now for the fourth year, I guess). I'm looking forward to it.

Tuesday, June 28, 2005

Not allowed to send an e-mail to China?

Hmmm... Usually I get SPAM from China, but now I'm no longer allowed to send any e-mail to them. I tried with my university e-mail address and with my chilisoftware.net and opf3.com e-mail addresses. The e-mails were rejected both times by the servers of sina.com.

Nice new world ;-)

[Opf3] Deleting related objects

A few people have been asking me about the way how Opf3 deletes related objects from the storage.

The quick answer: it doesn't.

The longer answer:
The framework does not delete the related objects because this would mean to load them all into memory, mark them for deletion and then delete them. That costs a lot time and is not praticable.

How to have related object deleted then?
We suggest to mark the relation in the storage with a "cascade delete". This means that the related objects are deleted when the parent object is deleted. We think that using "cascade delete" is the best way of doing it, because it's very fast as it is done by the storage.

Monday, June 27, 2005

Nice to know

Wow! The .NET community is really productive in creating new languages for the platform.

Saturday, June 25, 2005

[Opf3] Why does ObjectContext inherit MarshalByRefObject?

The ObjectContext class inherits MarshalByRefObject because it manages local resources (instance of storages etc.). The instances of ObjectContext should not be serialized during Remoting but a proxy class should be generated and send to the client. This can be accomplished by deriving from MarshalByRefObject.

[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.

Friday, June 24, 2005

[Opf3] Any questions?

Do you have any questions on Opf3? Please visit the Opf3 forums to post your questions.

[Opf3] What uses the ObjectReader to get the data?

The ObjectReader has to get an object that implements the IDataReader interface to retrieve the data from the storage. The constructor (which is internal right now - to avoid people to create ObjectReader from nowhere) takes an instance of a class that implements the IDataReader interface.

Internally the ObjectReader loops over the items in the IDataReader and queries the fields to populate the objects. To say the truth it isn't even the ObjectReader who populates the persistent objects. The ObjectReader navigates only to the row. The current row is then given to the ObjectDataAdapter (an internal class found in the Chili.Opf3.Storages namespace) which checks the fields in the row and populates the persistent object with data.

The ObjectDataAdapter is actually an interesting class for people who want to understand how the mapping between storage and persistent objects is working. The class has different methods to get data from the storage and to create a query expression that is used to insert, update or delete an object in/from the storage.

Test features in Whidbey: Thumbs up!

The test features in Whidbey are really cool. They are tightly integrated with the debugger (in Beta 2) and easy to use. I like that you have only to apply some attributes on classes and methods and Whidbey understands that those items are tests. Although it seems very similar to NUnit, but it seems to be the best way to do it.

I like the features of Whidbey to create the test stubs for existing classes! *thumbs up*

One thing I don't really like are the web tests. They are nice to create etc., but the output is almost never usable without any modifications.
One example is variable parameters in the URL of the web page (which happens very often). The user browses for example to the user overview and create a new user. Then she/he tries to edit that user (the url of the page would be for example EditUser.aspx?Id=342). After that she/he is going to delete the user. The next time the test runs it creates a new user but tries then to navigate to EditUser.aspx?Id=342. The user with that ID does no longer exist.
The only way I was able to make such tests working is to create a "coded" version of the webtest and edit it manually. I guess it's the only way, because Whidbey can't guess the IDs without some help :)

Thursday, June 23, 2005

Channel9 videos rock!

Hi guys, yesterday I watched the clip (Part 1) of the Channel9Guy going to PDC. It's awesome.

Another clip, I like very much, is the video on the mennonites in Ontario done by Jamie of Channel9. It's weird and at the same time interesting to know that there is people still living like 100-150 years ago.

Tuesday, June 21, 2005

How to extract data from an unstructured document?

The problem of extracting data from an unstructured document is quite challenging. It is really hard to extract data from a PDF document and bundle it with some useful semantic information. Some ideas on how elements on a page can be identified and classified are found in my short paper "Ideas for extracting data from unstructured documents".

This paper is the result an internship at the database and artificial institute of the technical university of vienna.

[Opf3] How does Opf3 decide if an persistent has been changed

How does Opf3 that actually do?

In the case you are using a ConcurrencyManager that's the work of that class. The Md5ConcurrencyManager (for example) creates the Md5 of all the properties of the current object and checks that Md5 with the one that has been created after the last operation on the storage.

Example:

// .. Other code.
// Create an ObjectContext.
ObjectContext context = new ObjectContext(storage);
context.ConcurrencyManager = new Md5ConcurrencyManager();

// Loads an user object from the storage. While loading the
// Md5 for that object is generated and stored internally with the
// data for the object.
User user = context.GetObject<User>("Name = {0}", "john");

// While saving the object the Md5ConcurrencyManager creates a new
// Md5 checksum on the properties of the object. Since we haven't
// changed anything the object is not saved.
context.PersistChanges(user);

// We change something.
user.Name = "New Name";
// The Md5 of the current instance is created and the
// Md5ConcurrencyManager understands that the object has been changed
// in memory since the current Md5 is different from the on that
// has been created during load.
// After the update the Md5 for the instance is set to the new one.
context.PersistChanges(user);


If you are working without any ConcurrencyManager, Opf3 fires an update query for every object that is persisted. Not using a ConcurrencyManager is only useful if you do a batch update. There you don't need those checks at all.

This example shows how this issue is solved with the Md5ConcurrencyManager (the only one that comes with Opf3 until now). If you are implementing any other ConcurrencyManager (by implementing the IConcurrencyManager interface) you have to deal with that issue by your own. You could, for example, have each persistent implement an interface that allows the ConcurrencyManager to check if the object has been changed.

Sunday, June 19, 2005

Studying, studying, studying, ...

I'm studying! It's the best weather outside and I'm sitting in the shadow to study. I have a few exams next week and I don't want miss them!

*smoke comes out of my head*

[Opf3] How is Opf3 dealing with connections to the storage?

Opf3 is using ADO.NET connection pooling. The framework creates a new connection for each operation that is done on the storage. But, if the ADO.NET connection pool is not empty .NET takes the connection directly from that pool.

Example: If you are loading an ObjectSet with, let's say, > 1000 objects Opf3 creates only one connection and loads those objects using that connection. Internally when loading the ObjectSet, Opf3 creates an ObjectReader instance and populates the ObjectSet using that instance.

Transactions?
On transactions the behaviour work a little bit different. When initializing a transaction Opf3 creates one connection and caches that one until the transaction has been committed or rolled back. A transaction is always bound to one connection.


The biggest benefit of using the connection pool of ADO.NET is multiple ObjectReader at the same time. Without any problems (and on any storage) you can create multiple instances of the ObjectReader at the same time. That's only possible because each ObjectReader has his own connection.


// Get the first ObjectReader.
ObjectReader<User> or1 = context.GetObjectReader<User>("UserName Like {0}", "%John%");
// We don't close the first ObjectReader but get also a second instance.
ObjectReader<User> or2 = context.GetObjectReader<User>("UserName Like {0}", "%Smith");
// And a thirth ObjectReader working on calls.
ObjectReader<Call> or3 = context.GetObjectReader<Call>();
// ...

// Dispose the objects. The order is not important.
or2.Dispose();
or1.Dispose();
or3.Dispose();


The following example uses only one connection (because we use a transaction there). All objects in the ObjectSets are saved using the same connection!


context.StartTransaction();

try
{
   // Save all changes.
   context.PersistChanges(objectSet1);
   context.PersistChanges(objectSet2);
   // Commit the transaction
   context.Commit();
}
catch (Exception ex)
{
   context.Rollback();
   throw;
}

Tuesday, June 14, 2005

[Opf3] What's new?

Hi,

There haven't been any new releases for Opf3 for the last month. What are we doing right now?

We are developing a wizard that allows you to create the persistent objects from a database and synchronize the persistent objects (of a current project) with the database schema. Those new features take us quite a time to develop, because we want to create something that is very flexible and easy to use.

By now, I can't show you any screenshots of the new "Opf3 Studio". We are in an early stage with the studio but as soon as possible I will post something more.

By the way: everybody who bought Opf3 gets the Opf3 Studio for free! :-)

Wednesday, June 08, 2005

University can be entertaining

Look at the following two pictures:

Count the black dots



Straight horizontal lines




I knew the first one, but I didn't know the second one.

Monday, June 06, 2005

The new speech API in Avalon

I recently watched the video about the speech API in Avalon. It looks really great for me - so simple and clean. Keep up the good work guys!

[Opf3] New mapping engine

We created a new mapping engine for Opf3. From the point of view of the developers using Opf3 nothing changes. Under the hood we made a lot changes. Opf3 does now also allow to override mapped properties without setting the FieldAttribute again. For example:


[Persistent("FOO")]
public class Foo
{
   private string _bar;

   [Field("BAR")]
   public virtual string Bar
   {
      get { return _bar; }
      set { _bar = value; }
   }
}

public class Foo1 : Foo
{
   public override string Bar
   {
      get { return base.Bar; }
      set
      {
         if (value == null)
            throw new Exception("Not valid.");
      }
   }
}

// Other code.

// Load the first object of Foo1.
// The overriden Bar is populated as the FieldAttribute
// on the property in the base class counts.
Foo1 foo = context.GetObject<Foo1>();


To map the override property to another field simply set the FieldAttribute on the ovverriden property. The new FieldAttribute overrides the one of the base property.

As another feature the new mapping engine allows also to map fields to fields in the storage.


[Persistent("FOO")]
public class Foo
{
   [Field("BAR")]
   public string Bar;
}


The new engine will go online with the next release of Opf3.