I used db4o in my code because of the simplicity, and native object storage. If you have never used db4o, I suggest it.
Also, this provider required explicit disposal, so I went back and implemented IDisposable on the Repository and the SingleServiceProvider.
Usage:
var r = new Repository();
r.RegisterServiceProvider(new SingleServiceProvider());
r.Register<IObjectContainer, SingleServiceProvider>(() => Db4oFactory.OpenFile("test.db"));
r.RegisterServiceProvider(new DB4OSingleServiceProvider(r.GetInstance<IObjectContainer>()));
r.Register<IMyClass, DB4OSingleServiceProvider>(() => new MyClass("a"));
IMyClass m = r.GetInstance<IMyClass>();
r.Dispose();
Code:
public class DB4OSingleServiceProvider : IRepositoryServiceProvider, IDisposable
{
private readonly Dictionary<Type, object> objects = new Dictionary<Type, object>();
private readonly IObjectContainer container;
public DB4OSingleServiceProvider(IObjectContainer container)
{
this.container = container;
}
~DB4OSingleServiceProvider() { this.Dispose(false); }
public void Remove(Type targetType)
{
var resultSet = this.container.Query(targetType);
while (resultSet.HasNext())
{
this.container.Delete(resultSet.Next());
}
this.container.Commit();
}
public void Update(object o)
{
this.container.Store(o);
}
#region IRepositoryServiceProvider Members
public void RegisterService(Type targetType, FactoryDelegate factoryMethod)
{
var resultSet = this.container.Query(targetType);
if (resultSet.Count < 1)
{
this.container.Store(factoryMethod());
}
}
#endregion
#region IServiceProvider Members
public object GetService(Type serviceType)
{
return this.container.Query(serviceType).Next();
}
#endregion
[ IDisposable Members … ]
}
I have not resolved how to handle events when the object has not been re-hydrated or dealing with multiple applications touching the same object database. Perhaps I will think about that some other time.
The biggest thing I have learned from this is that building something myself helps me understand. Now I am going to to try Autofac.