3

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:

enter image description here

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?

10
  • So what prevents you from making the DBContext short-lived? Commented Mar 30, 2017 at 18:55
  • Well, it would break lazy-loading (so effectively property relationships, unless explicitly loaded), and while it would make the API more verbose (Instead of getting the related item you'd have to always get entities directly from the repository) it would completely break the OnSave functionality.
    – Joe
    Commented Mar 30, 2017 at 20:22
  • So, it would be possible, but instead of getting an Element and using it, you do Repository.GetElement(id), then Repository.GetProperty(id) and instead of just using the objects and them being up to date, you'd have to all Repository.UpdateElement(newElement) and UpdateProperty etc etc. But you don't need to call UpdateProperty if it's a stream property. Kind of defeats the point of using Entity Framework at all, because I get none of the advantages of it. Might as well just wrap a few queries?
    – Joe
    Commented Mar 30, 2017 at 20:26
  • I could wrap the Entity Framework objects in a more fleshed-out object and kind of perform my own lazy loading? That seems like a really bad idea though.
    – Joe
    Commented Mar 30, 2017 at 20:33
  • Might as well just wrap a few queries? -- Not a bad idea here. Using ADO, ExecuteQuery or a micro-ORM like Dapper might all be better solutions than EF. Commented Mar 30, 2017 at 20:58

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.