I'm trying to build a 'distributed' data system. My first attempt is built using Entity Framework.
Very loosely, it's built around having
Element objects, which themselves have a group of
Property objects. Much like class objects and their properties.
The reason is that any changes to these are synchronized between the distributed modules with a messaging system.
So, say I've got a little service that reads some hardware. It has the "Fridge"
Element with the
Property "Temperature". If this
Property value changes, it's set like this:
TemperatureProperty.Value = 1234;
the messaging system picks that up, and if the property has the flag
IsStream, submits a message and all the other modules receive the update and fire an OnValueChanged event. (It also prevents this from being written to the database).
So the user interface, on a different computer, has it's temperature property receive a message, update and fire off the event. The UX knows about the change and can display the new value.
Similarly, other changes that are less common, but also need a reaction (say a new
Element), a "Configuration" change request is sent out. This just tells the recipient that the object they have is out of date.
I'm using a central Repository. The whenever an object is requested from the repository (or lazy loaded) it wires up any relevant events. Streamed values are immediately dispatched over the message system, other changes are tracked and propagated with the OnSave method:
My whole ethos was making the API as easy as possible. You don't have to know there's a message service, or whether this property is streaming, sending out configuration changes, or anything if you don't need to.
You just care that you've got a Temperature property, and it has a new value, so you set it. Or the values has changed, so you do something. Everything else is maintain managed by the 'framework'.
However, this results in a very long-lasting DBContext. The entity framework is always 'active'. This is really nice to work with, as lazy loading makes things work really well.
But I'm reading more and more that the DBContext should be short-lived, and certainly not kept 'online' for application-length time-spans.
With these little hardware services, the DBContext would be sitting there 24/7 to keep things up to date.
I also tried to create my lovely "just use it like any other thing"
Property in a test service - except I did the hardware reading in a Task (so on a different thread. Well, of course, all hell broke lose because DBContext isn't thread safe.
Does anyone have any advice on how to maintain the features, the on-save change tracking, but incorporating the "Unit of Work" type structure?
Or should I re-think the whole architecture and try move away from the repository pattern?