I may be doomed by an impedence mismatch, but I'm trying to reconcile examples I've seen for IRepository and immutable objects.
I'm working on a cataloging application where hundrds of web requests operate on a 'working set' of products - a subset of the whole catalog tends to be in play at any given time.
At the same time, our data teams constantly update product data - new images, updated pricing, descriptions, etc. etc.
It seems to me that for performance I'm better off considering a product as immutable. They are loaded and cached by a repository and many threads can be accessing the same product object at the same time.
But this idea seems broken with many of the IRepository examples I've seen with Update/Delete methods - as soon as a thread can write to a product it seems like I open myself up to races and other nastiness.
So I envisioned an 'editor' model where changes to an entity are made via a companion 'editor' object that then persists the changes and forces the product in question to be reloaded for everyone to use. Products are never changed - only 'edited' externally and reloaded.
Does this make any sense? Can this work with a repository as I've seen them described?
A repository is only responsible for data retrieval/storage. A factory is responsible for creating new objects.
In your case, immutable objects are ok. However you need some method to invalidate superseeded products and remove them from the repository cache. Any dangling references can be neglected in most cases, as they were valid at retrieval time.
In case of a product update you need to make sure that you create a new product via the factory. Your repository would only include three operation kinds: Retrieve (or Find), Save and Supersede. Where Save stores a new product, which is not changed. And Supersede would store the new product, invalidate the old and purge it from the cache.
In terms of a C# signature I could imagine the two storage methods to take the following appearance:
void Save(Product product);
void Supersede(Product oldProduct, Product newProduct);
I hope this helps.