Update 2 : @Enigmativity has a brilliant answer. I\'ve implemented this into a IObservableRepository
. Details in my answer below.
Just a quick, off the cuff answer.
How about using the Reactive Extensions for .NET (Rx)?
You could then define your repository as:
public interface IObservableRepository where T : class
{
IObservable GetById(int id);
IObservable GetAll(Func, IQueryable> query);
IObservable InsertOnSubmit(T entity);
IObservable DeleteOnSubmit(T entity);
IObservable SubmitChanges();
}
All of the returned observables would contain single values, except for GetAll
which would have zero or more.
The Unit
type is void
in the Rx world. It's just a way of not needing to define a non-generic IObservable
interface.
You would then query like so:
IObservableRepository repo = ...;
var foos = repo.GetAll(ts => ts.Where(t => t.Bar == "Hello"));
foos.Subscribe(foo =>
{
// Do something asynchronously with each `Foo`.
});
And submit could be done like this:
var submit =
foos
.Select(foo => repo.InsertOnSubmit(foo)).ToArray()
.Select(s => repo.SubmitChanges());
submit.Subscribe(result =>
{
// handle the asynchronous result of submit.
});
This is all based on trying to keep the repository methods as close as possible to the original, but it may be worth refactoring on the Silverlight side to something like this:
public interface IObservableRepository where T : class
{
IObservable GetById(int id);
IObservable GetAll(Func, IQueryable> query);
IObservable Submit(T[] insertsOrUpdates);
IObservable Submit(T[] insertsOrUpdates, T[] deletes);
}
Submit would be a bit nicer now:
repo.Submit(foos).Subscribe(result =>
{
// Handle asynchronous result of submit;
});
Like I said, off the cuff. :-)