March 2013 Code Update - Overview

Mar 20, 2013 at 6:45 AM
Edited Mar 21, 2013 at 7:42 PM
Hi folks

Wanted to give some overview of what's in the last push, what to look at. Updating documentation will take some time, so here's a brief guide on new items and concepts.
  1. First of all, all Web stuff is gone. Bye-bye, WCF, we'll not gonna miss it. We use WebApi for web services (at my company) on top of VITA-based data access, that's easy and (almost) painless. In the future I will probably add a project that combines some common Vita-WebApi bridge features, to make it even easier for everybody.
  2. VITA's internal model is refactored with the purpose of easier extensions. In fact, much of the current VITA functionality is implemented as 'extentions' over core model (like many of the entity attributes). You can easily 'hook' into the internal model/engine, and inject some custom behavior. You can create your own attribute, slap it on your entities or properties and have your custom behavior invoked automatically. Look at attributes that come with VITA for an example. The other way to hook into the model is from custom modules - like ChangeTracking module hooks to Save event of the entity store, and automatically records changes of 'watched' entities in tracking table.
  3. New class UserContext - for keeping information about the current end user. You can specify it as a parameter to EntitySession constructor. Some auto behavior (like CreatedBy columns) use this information to set the fields (CreatedBy is set to current user's name taken from the UserContext). Authorization framework relies on this object when evaluating access rights for the current user.
  4. Several new model attributes, and new features of old attributes. Notice the cute PersistOrderIn attribute - allows you automatically save the order of child lists in entities by setting the 'line-number' column in each child. Other enhancement: Index columns can be specified with Asc/Desc order.
  5. Notice new Log implementation. Log formatting and writing to disk is done on a background thread, so main thread executing data access just pushes unformatted entries into the asyns queue, with minimal performance impact. All log entries are SQL-formatted, so fragments of log may be copied into SQL query window and executed directly. Enable logs when you play with the system, and look what's there after test execution. It reports commands, execution time, # of records returned; it shows if operation is executed in entity cache, etc. To examine entity cache behavior, the tool #1 is log.
  6. LINQ handling is completely rewritten. Creating custom queries (converted to stored procs) in modules is simplified, and the process is more clear. Dynamic queries are compiled and saved in compiled query cache, to be reused on subsequent calls.
  7. Entity cache - full-blown cache, delivering not only 'get-by-id' records, but executing ANY dynamic Linq query against cached tables. BooksSample tests have cache enabled by default, so run these tests and look at the log, to see which queries were served from cache. There is also a separate 'sparse cache' - cache of single records.
  8. Role-based Authorization framework. This is the real jewel, the piece I'm really proud of. The best way to see how it works is to look at BooksSample, authorization roles setup, and then go step-by-step through the AuthorizationTests in unit tests. Notice that authorization code is completely outside the 'mainstream' logic code - you setup Roles/permissions at application startup; then in your business logic you open a Secure session, and do whatever your business code needs to do - never thinking about permissions for particular piece of data; authorization framework will throw AccessDenied as soon as you touch the data that the current user is not allowed to see. Those of you folks who ever wrote or maintained a business app - all of which have some ugly authorization subsystem - you would certainly appreciate what VITA offers for authorization.
  9. Code generation for db-first approach. VITA includes a command line tool that generates entity definitions from the pre-existing database. All parameters are stored in .config file, and name/path of this file is specified as a command line parameter. The tool itself (the project) includes a few config files for MS demo databases - download and install databases from MS download site, and then run the tool to see how it works.
    The generated c# file contains entity definitions, module classes (one module for each schema), entity model class, and even static Program class with Main method that may be run in console application. The generated code contains most of the database elements - including keys and indexes, so that if you run it against an empty database, it will recreate the entire schema. In fact, the generator runs the check of the result code - it compiles it, builds the data model from it, and then compares it to the original database, reporting any differences - hopefully none.
    Notice that entities/properties in the generated code might have slightly adjusted c#-fied names. But there's always a link to the original column/table name. Each property is marked with [Column("real_column_name")] attribute. You are now free to modify the c# definitions using VS refactoring tools any way you want, but the system will keep finding the correct association with database objects. Notice that indexes and table keys list column names, not property names in string arguments - to allow changing property names freely. Try it if you have an existing database, then run the generated console app, write some queries. By default the system will NOT modify anything (schema objects) in database, and will use direct SQL queries for CRUD operations. Change the 'updateSchema' parameter to 'true' at startup, system will generate CRUD stored procs and will use it all read/writes.
    Another interesting feature. As an example, let's say your database uses Date SQL type, so the generator will produce a DateTime property in c# interface (.NET has no Date type). But for DateTime c# type, the default db column type is DateTime2, and db schema updator would generate this column type by default. To override this default, there is a DbType parameter in Column attribute that can be set to specific DbType. For non-standard DbTypes in MS SQL Server (like Image) you can use extra values defined in the CustomDbTypes class. Using this DbType parameter allows you to reproduce the exact database schema, even if it uses exotic types like 'char(n)'.
  10. Some other interesting features. RowVersion (timestamp) support - CRUD methods for tables with RowVersion columns automatically check the row version of the record being updated, and throw error on mismatch.
11 Standard modules. There are several standard modules in Vita.Modules assembly.
  • ErrorLog - for logging errors/exceptions in the database. Ready to use.
  • Login - for storing user logins (password hashes) and performing logins. Uses RFC2898 algorithm, recommended for password hashing. Ready to use in real apps
  • ChangeTracking - for recording all changes (inserts/updates/deletes) to selected set of entities/tables. For each transaction, the list of changes (Entity type/PrimaryKey/Operation) as text is written to the table ChangeTrackEntry. One useful feature is ability to classify the updates into separate groups. For example, if your app serves several customers, the tracking system can write changes of data 'belonging' to each customer in a separate record, and with ChangeTrackEntry.Partition column set to CustomerId. Then when we need to query all changes for a customer, we can easily do it using this Partition column. This is used in Data syncing, when we want to sync remote customer databases with only data belonging to this customer. (We do this in our application). This module works OK, although there's a flaw in design - it relies on date ranges to group changes (for sync). This actually causes problems when client clock in not quite in sync with server's. I plan to switch to more reliable system with increasing version number. So consider this module 80% usable, whatever it means.
  • DataSync module - for syncing databases. It uses change tracking module to get the list of changes that needs to be exchanged with remote database. It works OK in our app, but honestly, I'm not happy with some design decisions and plan some improvements. My advise - do not use it for now.
  • PasswordReset - just draft of entities, no working code yet.
So, I think that's all for now. Hope you'd like it, my friends!
Mar 29, 2013 at 10:56 PM
VITA Tutorial is updated:
Developer Guide will follow.
May 3, 2013 at 9:41 PM
VITA Authorization Framework document posted in Documentation: