Why Neo?
The following is a list of five technical reasons why people use Neo. Of course, there are non-technical reasons as well: Neo is Open Source and has an active user community. It is being used on several large commercial projects and its feature set and performance have been tuned on these. At the same time, it is still in active development and we are adding advanced features. Okay, enough of this and on to the technical benefits.
Because it is simple and object-oriented
The following code snipped shows how to load all titles (i.e. books) that were published before a certain date, apply a clearance discount and then save the changes to the database:
IDataStore datastore = new SqlDataStore(" database connection string "); ObjectContext context = new ObjectContext(datastore); TitleFactory factory = new TitleFactory(context); TitleList matchingTitles = factory.Find("PublicationDate < {0}", new DateTime(2003, 1, 1)); foreach(Title title in matchingTitles) title.ApplyClearanceDiscount(); context.SaveChanges();
Where ApplyClearanceDiscount() could look like:
public void ApplyClearanceDiscount() { this.Price = this.Price * (1 - GetClearanceDiscount()); }
Note that you can add custom methods such as ApplyClearanceDiscount() and GetClearanceDiscount() to your domain objects, something that is not possible with typed datasets. Of course, all the code is strongly typed, and even better, all the typed flavours of list, factory etc. are automatically generated for you.
It manages the domain model
The model is defined in an abstract format and Neo creates extensible base classes that handle data storage, change tracking, sending of events etc. Other frameworks use normal objects for the domain model, which also has some advantages but limits what the framework can do for you. Say, you want to add a title to the list of titles of a given publisher. In Neo, and most other frameworks, you would do this somehow like this:
aPublisher.Titles.Add(theTitle);
Normally, the title object also knows its publisher and if you use plain objects you must not forget to set this, or else your domain model becomes inconsistent. In other words you also need the following:
theTitle.Publisher = aPublisher;
With the domain model created by Neo, you can do either and the framework ensures that the model remains consistent.
It manages persistence
In short: You deal with objects and objects only. All queries are expressed in terms of classes and properties with Neo creating the required SQL statements at runtime. Updates are generated automatically based on change tracking information and there are tools to create the database schema from your model definition.
Neo uses a generic persistence framework and specialised implementations for different databases so that it can go beyond the features offered by plain SQL92.
It can work disconnected
Neo has a powerful implementation of the unit of work pattern. The ObjectContext class offers several features that go beyond what one normally expects from a unit of work implementation, which is the reason why it has a more generic name than just UnitOfWork.
One of the features is that an ObjectContext does not need a connection to a database. It can even start out connected, with features like lazy-loading enabled, and later on disconnect so that all queries run against the data available in memory only. Of course, changes can still be saved to the database.
An ObjectContext can also work completely stand-alone, in which case you can use ADO.NET DataSets to get data into and out of the context. Like this for example:
ObjectContext context = new ObjectContext(); context.MergeData(someDataSet); // use the objects to change data like above, then... changeDataSet = context.GetChanges();
One of the scenarios where this comes in handy are rich-clients that only occasionally connect to the server. You can take the change set, send it to the server process and create a new ObjectContext in that process, this time with a database connection, and use it to save the changes. This means that the server can remain stateless.
It is suited for test-driven development
Neo itself was written test-first and it uses many design principles that make testing easy. Key classes such as ObjectContext and the factories can be created with simple a constructor and they take objects they depend on as parameters in the constructor; rather than using locators to retrieve them. This is known as dependency injection and allows for easy substitution in tests.
Despite the fact that Neo does not use plain objects for the domain model, it is very easy to create domain models in tests without having to work with a database. This is achieved with the same technique that allows Neo to work disconnected.