Search code examples
mvvmioc-containerautofacdb4o

How to integrate db4o and autofac for my Model objects?


I can see how I can instantiate objects of classes using autofac, and then pass these to db4o for storage. When it's time for me to retrieve the object instances from db4o, how do I register the objects with autofac?

I was originally planning on using db4o's MSBuild tool to implement transparent activation/persistence, but it looks like that I may have to manually implement the IActivatable interface for all my Model objects so that I can put in extra code in IActivatable::Bind() to register this pointers as they are activated.

To make matters worst, I foresee that the implementation of IActivatable::Bind() will have to access a Singleton of the current Autofac lifetime scope to do the registration against. Obviously, I can't pass in the current lifetime scope to the object instance that db4o is activating. As bad as passing the scope around is, I can imagine the groans from people considering sticking the current life scope in a public Singleton.

An alternative seems to be to implement db4o's Type Handlers and intercept object instantiation at that point, but that seems like undoing any gains I had of using db4o for storing objects.

Or did I just go a little too crazy with the idea of using autofac to instantiate all objects? (e.g. I've got a hammer and everything looked like a nail.) Should Model objects just be instantiated by plain old 'new' and whatever magic that db4o uses? In other words, use autofac only with my View, ViewModel and Controller objects.


Solution

  • I would recommend to replace every 'new' with an Autofac instantiation. My rule of thumb is that I when a object needs complex dependencies (not simple collections, core CLR types, other simple objects), then I let Autofac do the work. Simple domain object I usually just use the new operator or a create a factory.

    I'm not 100% sure if I get your question right. You want to bind some service to your domain models when they are instantiated? Well then I recommend to use events. You can use the db4o events to detect when an object gets stored, activated, etc. In such a event listener you can use the current Autofac scope to pass additional services.

    Btw. the IActivatable::Bind() stuff is already called by db4o. You don't need to do anything else.

    In general I would try to properly scope everything and not misuse Autofac as a service-locater.