Your questions
To share or not share the ObjectContext for my situation? Do not share your context. The EntityFramework context must follow the UnitOfWork pattern. The context of your object should be as short as possible, without the need to create / destroy too many contexts. This usually refers to the individual “operations” in your application as units of work. For a web application / api, it can be for HttpWebRequest , or you can do it for the operation of logical data (for each of the implemented parts of the "Business Logic").
For instance:
LoadBusinssObjects() will create a context, load your list of data and any data associated with it, and then delete the context.CreateBusinessObject() will create a context, create an instance of some object, fill it with data, bind it to collection in the context, save the changes and delete the context.UpdateBusinessObject() will read some object from the context, update it, save changes and delete the context.DeleteBusinessObject() will find the business object in the context, delete it from the collection in the context, save the changes, and delete the context.
If not shared, how can I solve my current problem of updating one objectContext with changes made to others? This is a job for pub / sub architecture . It can be as simple as several static event handlers on your objects for each operation described above. Then, in your code for each business transaction, you fire up the corresponding events.
If to share - what would be better? Static or singleton or something else? This is not true. The EF context will continue to grow in memory, as the context manager continuously collects cached objects (both attached and unconnected) for each individual interaction that you make in your application. The context is not intended to work as follows.
In addition to using resources, the EF context is not thread safe. For example, what if you want one of the forms in your editor to save some changes at the same time that the tree list loads some new data? With one static instance, it’s better to make sure that all this works in the user interface thread or synchronized with the semaphore (yuck and yuck - bad practice).
Example
Here is an example of using C # and the first approach code according to your post. Please note: I am not considering things like data concurrency or threading so that this example is short. Also in a real application, this concept is implemented using generics and reflections, so that ALL of our models have basic events for them to create, update, delete.
public class MyCodeFirstEntityChangedArgs : EventArgs { /// <summary> /// The primary key of the entity being changed. /// </summary> public int Id {get;set;} /// <summary> /// You probably want to make this an ENUM for Added/Modified/Removed /// </summary> public string ChangeReason {get;set;} } public class MyCodeFirstEntity { public int Id {get;set;} public string SomeProperty {get;set;} /// <summary> /// Occurs when an instance of this entity model has been changed. /// </summary> public static event EventHandler<MyCodeFirstEntityChangedArgs> EntityChanged; } public class MyBusinessLogic { public static void UpdateMyCodeFirstEntity(int entityId, MyCodeFirstEntity newEntityData) { using(var context = new MyEFContext()) { // Find the existing record in the database var existingRecord = context.MyCodeFirstEntityDbSet.Find(entityId); // Copy over some changes (in real life we have a // generic reflection based object copying method) existingRecord.Name = newEntityData.Name; // Save our changes via EF context.SaveChanges(); // Fire our event handler so that other UI components // subscribed to this event know to refresh/update their views. // ---- // NOTE: If SaveChanges() threw an exception, you won't get here. MyCodeFirstEntity.EntityChanged(null, new MyCodeFirstEntityChangedArgs() { Id = existingRecord.Id, ChangeReason = "Updated" }); } } }
Now you can attach event handlers to your model from anywhere (its static event handler) as follows:
MyCodeFirstEntity.EntityChanged += new EventHandler<MyCodeFirstEntityChangedArgs>(MyCodeFirstEntity_LocalEventHandler);
and then a handler in each view, which will update the local user interface views each time this event fires:
static void MyCodeFirstEntity_LocalEventHandler(object sender, MyCodeFirstEntityChangedArgs e) {
Now, every user interface component that you have can subscribe to what events are important to it. If you have a list of trees, and then some form of editor, the list of trees will subscribe to any changes to add / update / delete node (or a simple way - just update the list of the whole tree).
Cross-Application Updates
If you want to take another step and even bind individual instances of your application in a connected environment, you can implement a pub / sub-event system on the network using something like WebSync - a comet implementation for the Microsoft technology stack . WebSync has everything that was built in to split events into logical “channels” for each object / event you want to subscribe to or publish to. And yes, I work for a software company that makes WebSync - they pay for my time when I write this. :-)
But if you do not want to pay for a commercial implementation, you can write your own client / server for the TCP socket, which distributes notifications for the above events when the entity changes. Then, when the subscribed application receives a notification over the network, it can launch its local event handlers in the same way, which will lead to the updating of local views. You cannot do this with a poorly archived static instance of your data context (you will only have one instance of your application). With some good settings at an early stage, you can easily hide in the distributed pub-sub system later, which works simultaneously with several instances of native applications and web applications! It is becoming very powerful.