v1.10.0: .NET 4.5, MVC5, JSON remoting; improved NuGet and Windows services support

The summary below describes major new features, items of note and breaking changes. The full list of issues is also available for those with access to the Encodo issue tracker.

Highlights

Breaking changes

Utilities

  • PathTools.Canonicalize() has been replaced with FileTools.Canonicalize().
  • ICredentials.Password no longer exists; instead, use ICredentials.PasswordHash.
  • The ReversibleEncryptionProvider no longer exists; instead, use the RijndaelEncryptionProvider.
  • UrlParts.Protocol no longer exists; instead, use UrlParts.Scheme.
  • DirectoryServicesSettings.ServerUri no longer exists; instead, use DirectoryServicesSettings.HostName.

Configuration

  • The extension method CoreConfigurationTools.Integrate() no longer exists; instead, use ConfigurationTools.Add(). If you still need to clear existing packages, call StartupActions.Clear() and ShutdownActions.Clear() before adding the package.
  • MetaConfigurationTools.IntegrateMongoLoopbackDatabase(), MetaConfigurationTools.IntegrateLocalDatabase and MetaConfigurationTools.IntegrateLoopbackDatabase() no longer exist. Instead, the MongoLoopbackDatabase is the default provider registered for the ILoopbackDatabase interface. If the configuration of an application requires a loopback database, the version provided by the ServiceLocator will provide it. Override that registration to change the type of database to use.
  • The class Encodo.Quino.Tools.DataGenerator has been moved to the Encodo.Quino.Models.Tools.DataGenerators namespace.

Metadata/Builders/Modules

  • MetaBuilderBase.ApplyGenerators() no longer exists; instead, use MetaBuilderBase.Commit().
  • The attribute Encodo.Quino.Methods.AspectsBaseAttribute has been replaced with Encodo.Quino.Meta.Aspects.AspectProviderAttributeBase.
  • The interface Encodo.Quino.View.Aspects.IViewColorAspect and class ViewColorAspect have been replaced with the Encodo.Quino.View.Aspects.IViewAppearanceAspect and ViewAppearanceAspect, respectively.

Reporting

  • The class Encodo.Quino.Models.Reports.ReportsModuleGenerator has been moved to the Encodo.Quino.Models.Reports.Generators namespace.
  • The aspect Encodo.Quino.Models.Reports.ReportContextVisibleAspect has been moved to the Encodo.Quino.Models.Reports.Aspects namespace.

Security

  • The aspect Encodo.Quino.Models.Security.SecurityContextVisibleAspect has been moved to the Encodo.Quino.Models.Security.Aspects namespace.
  • The aspect Encodo.Quino.Models.Security.SecurityModuleSecurityClassAspect has been moved to the Encodo.Quino.Models.Security.Aspects namespace.
  • The class Encodo.Quino.Models.Security.StandardSecurityModuleAccessControl has been moved to the Encodo.Quino.Models.Security.Logic namespace.
  • The class Encodo.Quino.Security.LoginTokenBasedLoginAuthenticator has been replaced with the Encodo.Quino.Models.Security.Login.SecurityModuleTokenBasedAuthenticator.
  • The class Encodo.Quino.Security.UniqueIdentifierBasedAuthenticator has been replaced with the Encodo.Quino.Models.Security.Login.SecurityModuleUniqueIdentifierBasedAuthenticator.

Data providers

  • PostgreSqlMetaDatabase no longer has a constructor that accepts a string to name the database. The name is always taken from the ConnectionSettings.Name.
  • Database.RefreshState() and Database.DefaultConnectionSettings no longer exist; instead, use Database.RefreshDetails() and Database.ConnectionSettings, respectively.
  • Extension method MetaApplicationTools.GetQueryableDatabases(this IMetaApplication) has been replaced with extension method DataProviderTools.GetDatabaseHandlers(this IDataProvider).
  • Extension method MetaConfigurationTools.GetQueryableDatabases(this IMetaApplication) has been replaced with extension method DataProviderTools.GetDatabaseHandlers(this IDataProvider).
  • The IDataConnection.SyncRoot object no longer exists. Connections should never be shared between threads. Instead of explicit locking, applications should use an IPooledDataConnectionManager to maximize sharing of connections between threads.
  • The method IPersistable.SetStored() no longer exists; instead, use SetState().
  • IPersistentObjectContext no longer exists; instead, use IPersistentObjectContext.InitialObjectState.
  • The methods IMetaObjectHandler.GetObjectStored(), IMetaObjectHandler.GetObjectDelete(), IMetaObjectHandler.GetObjectChangedOrNew() and IMetaObjectHandler.SetObjectStored() no longer exist; instead, use some combination of IMetaObjectHandler.GetObjectState(), IMetaObjectHandler.GetObjectChanged() and IMetaObjectHandler.SetObjectState().
  • The NullCache no longer exists; instead, register an IDataCacheFactory with the ServiceLocator that returns a DataCache without any providers defined or has the property Enabled set to false.
  • The constant MetaActionNames.DetermineDatabaseState has been replaced with MetaActionNames.DetermineDataProviderConnectivity.

Remoting

  • The attribute Encodo.Quino.Methods.MetaMethodParameterInterceptorAspect has been replaced with Encodo.Quino.Methods.Aspects.MethodParameterInterceptorAspectBase.
  • The extension method MetaConfigurationTools.IntegrateRemoting() no longer exists. Remoting is now automatically configured to use the HttpRemoteClientFactory. To override this default behavior, use the ServiceLocator to register a different implementation for the IRemoteClientFactory.
  • MetaConfigurationTools.SetupForRemotingServer() no longer exists; instead, use MetaConfigurationTools.ConfigureAsRemotingServer().
  • The SetUpRemotingAction and MetaActionNames.SetUpRemoting constant no longer exist. Instead, the IRemoteClientFactory is configured in the ServiceLocator; override that registration to use a different implementation.
  • The constant RemoteServerDataHandler.DefaultName and method RemoteServerDataHandler.GetName() no longer exist; instead, use the name of the driver, which is derived from the name in the connection settings for that driver.
  • The interface Encodo.Quino.Remoting.Client.IRemoteMethodCaller has been moved to the Encodo.Quino.Remoting.Methods namespace.
  • The class RemoteClientFactoryAuto no longer exists. Remoting is now automatically configured to use the HttpRemoteClientFactory. To override this default behavior, use the ServiceLocator to register a different implementation for the IRemoteClientFactory.
  • HttpRemoteHost and RemoteHostHttp no longer exist; instead, use Encodo.Quino.Remoting.Http.MetaHttpRemoteHost.

Winform

  • WinformDxMetaConfigurationTools.IncludeSettings() has been replaced with the extension method WinformDxMetaConfigurationTools.IncludeWinformDxSettings().
  • WinformDxMetaConfigurationTools.ConfigureDefaults() has been replaced with the extension method WinformDxMetaConfigurationTools.IntegrateWinformDxPackages().
  • The method ControlToolsDX.FindProperty() no longer exists; instead, use the method ControlsToolsDX.TryGetProperty().
Apple Developer Videos

This article originally appeared on earthli News and has been cross-posted here.


It's well-known that Apple runs a walled garden. Apple makes its developers pay a yearly fee to get access to that garden. In fairness, though, they do provide some seriously nice-looking APIs for their iOS and OS X platforms. They've been doing this for years, as listed in the post iOS 7 only is the only sane thing to do by Tal Bereznitskey. It argues that the new stuff in iOS 7 is compelling enough to make developers consider dropping support for all older operating systems. And this for pragmatic reasons, such as having far less of your own code to support and correspondingly making the product cost less to support. It's best to check your actual target market, but Apple users tend to upgrade very quickly and reliably, so an iOS 7-only strategy is a good option.

Among the improvements that Apple has brought in the recent past are blocks (lambdas), GCD (asynchronous execution management) and ARC (mostly automated memory management), all introduced in iOS 4 and OS X 10.6 Snow Leopard. OS X 10.9 Mavericks and iOS 7 introduced a slew of common UI improvements (e.g. AutoLayout and HTML strings for labels).1

To find the videos listed below, browse to WWDC 2013 Development Videos.

For the web, Apple has improved developer tools and support in Safari considerably. There are two pretty good videos demonstrating a lot of these improvements:

#601: Getting to Know Web Inspector

This video shows a lot of improvements to Safari 7 debugging, in the form of a much more fluid and intuitive Web Inspector and the ability to save changes made there directly back to local sources.

#603: Getting the Most Out of Web Inspector

This video shows how to use the performance monitoring and analysis tools in Safari 7. The demonstration of how to optimize rendering and compositing layers was really interesting.

For non-web development, Apple has been steadily introducing libraries to provide support for common application tasks, the most interesting of which are related to UI APIs like Core Image, Core Video, Core Animation, etc.

Building on top of these, Apple presents the Sprite Kit -- for building 2D animated user interfaces and games -- and the Scene Kit -- for building 3D animated user interfaces and games. There are some good videos demonstrating these APIs as well.

#500: Whats New in Scene Kit

An excellent presentation content-wise; the heavily accented English is sometimes a bit difficult to follow, but the material is top-notch.

#502: Introduction to Sprite Kit

This is a good introduction to nodes, textures, actions, physics and the pretty nice game engine that Apple delivers for 2D games.

#503: Designing Games with Sprite Kit

The first half is coverage of tools and assets management along with more advanced techniques. The second half is with game designers Graeme Devine2 and Spencer Lindsay, who designed the full-fledged online multi-player game Adventure to showcase the Sprite Kit.



  1. Disclaimer: I work with C# for Windows and HTML5 applications of all stripes. I don't actually work with any of these technologies that I listed above. The stuff looks fascinating, though and, as a framework developer, I'm impressed by the apparent cohesiveness of their APIs. Take recommendations with a grain of salt; it could very well be that things are a good deal less rosy when you actually have to work with these technologies.

  2. Formerly of Trilobyte and then id Software, now at Apple.

ELI5 answer to: How and why do computer programs crash?

This article originally appeared on earthli News and has been cross-posted here.


ELI5 is the "Explain LIke I'm Five" forum at Reddit. I recently answered the question "How and why do computer programs crash?" and thought the answer might be worth cross-posting (even though the post itself never gained any traction).

What is a program?

Programs comprise a limited set of instructions that tell them what they should do when they encounter certain inputs under certain conditions.

Who writes programs?

People write computer programs. Therefore, programs only do what those people can anticipate. Unanticipated situations result in crashes.

Anatomy of a crash

A "crash" is when a program is no longer able to process further input.

Here's roughly how it works:

  • The environment in which the program runs applies input events to the program.
  • The program checks for an instruction that matches its current state plus the new input.
  • If one is found, it applies that instruction to create a new, current state.
  • A program "crashes" when it receives an input in a given state that it was not designed to handle.

Different kinds of crashes

This can happen either:

  • When the program enters an infinite loop and is no longer capable of responding to new input (sometime called "hanging").
  • When the program terminates itself as a result of not being able to handle the input ("hard crash" or "unhandled exception" or "segfault", etc.).

This does not mean that the program behaves unpredictably. The crash is perfectly predictable.

Avoiding crashes

Crashes can be avoided with one or more of the following:

  • Good design
  • Good programmers
  • Good libraries & programming languages
  • Good testers
  • Time
  • Money

Hope that helps.

v1.9.4: Bug fixes for 1.9.3 -- Reporting fixes and improvements

The summary below describes major new features, items of note and breaking changes. The full list of issues is also available for those with access to the Encodo issue tracker.

Highlights

  • QNO-4436: Generated objects can now hook events directly, instead of being forced to use aspects
  • QNO-4435: MetaBindingList no longer implicitly saves deleted objects
  • QNO-4434: Reporting: import for multiple reports works again (only the first report was imported)

Breaking changes

  • None
v1.9.3: Bug fixes for 1.9.2 -- Reporting fixes and improvements

The summary below describes major new features, items of note and breaking changes. The full list of issues is also available for those with access to the Encodo issue tracker.

Highlights

Breaking changes

  • None
Frans Bouma (founder/developer of LLBLGen) "discovers" Quino

Encodo Systems AG started work on its metadata framework Quino in late 2007. We've used it successfully in many projects, from Windows desktop applications to standalone servers, Windows services and web sites. It has grown considerably since its inception and the core concept of keeping the focus of an application on its metadata has stood the test of time quite well.

The recent article Code-first O/R mapping is actually rather silly by Frans Bouma recounts how the lead developer and architect of another popular ORM LLBLGen Pro, has also recently "discovered" the benefits of the metadata-first approach.

He writes,

Starting with code in the form of entity classes is equally odd as starting with a table: they both require reverse engineering to the abstract entity definition to create the element 'on the other side': reverse engineer[ing] the class to the abstract entity definition to create a table and the mappings is equal to reverse engineering a table to a class and create the mappings. [T]he core issue is that if you start with a class or a table, you start with the end result of a projection of an abstract entity definition [...]

What if that abstract entity definition which was used to create the class or table was in a model which contained all of the domain types for the domain used in the software to build? [...] it would give a couple of benefits: you can create overviews of the model and more importantly, changes in the domain can be applied directly into the model which then ripple through to classes and tables in the right form [...] (Emphasis added.)

He describes the core tenets of Quino rather well: starting with the metadata avoids diluting the domain model with the limitations of a projection domain (classes, tables, etc.). This has been borne out by our experience working in exactly this manner for the last several years.

The ORM in Quino is only a satellite component that leverages the centrally defined metadata just as many other components do. The programmer defines the metadata of the domain model and Quino provides tools to do many tasks automatically:

  1. Create or update a database schema
  2. Generate business-logic classes (primarily C# but it could be JavaScript or indeed any target language where code would benefit from strongly typed domain classes)
  3. Select/create/update/delete data in one or more databases
  4. Generate standardized user interfaces for multiple platforms
  5. Integrate with reporting engines and designers
  6. Generate UML diagrams
  7. ...and much more...

I heartily encourage Frans to continue thinking in this direction. He will be rewarded greatly for it.

v1.9.2: Bug fixes for 1.9.1 -- Reporting fixes and improvements

The summary below describes major new features, items of note and breaking changes. The full list of issues is also available for those with access to the Encodo issue tracker.

Highlights

Breaking changes

  • None
Entity Framework Generated SQL

This article originally appeared on earthli News and has been cross-posted here.


Microsoft just recently released Visual Studio 2013, which includes Entity Framework 6 and introduces a lot of new features. It reminded me of the following query that EF generated for me, way, way back when it was still version 3.5. Here's hoping that they've taken care of this problem since then.

So, the other day EF (v3.5) seemed to be taking quite a while to execute a query on SQL Server. This was a pretty central query and involved a few joins and restrictions, but wasn't anything too wild. All of the restrictions and joins were on numeric fields backed by indexes.

In these cases, it's always best to just fire up the profiler and see what kind of SQL is being generated by EF. It was a pretty scary thing (I've lost it unfortunately), but I did manage to take a screenshot of the query plan, shown below.

image

It doesn't look too bad until you notice that the inset on the bottom right (the black smudgy thing) is a representation of the entire query ... and that it just kept going on down the page.

How to fool people into giving up their email address

This article originally appeared on earthli News and has been cross-posted here.


On Codecademy, you can learn to program in various languages. It starts off very slowly and is targeted at non-technical users. That's their claim anyway -- the material in the courses I looked at ramps up pretty quickly.

Anyway, the interesting thing I saw was in their introductory test. It struck me as a subtle way to get you to enter your email address. I'd just recently discussed this on a project I'm working on: how can we make it fun for the user to enter personal information? The goal is not to sell that information (not yet anyway, but who knows what the future holds), but to be able to enhance -- nay, personalize -- the service.

Personalizing has a bad reputation but can be very beneficial. For example, if you're using a site for free and you're going to see offers and advertisements anyway, isn't it better to enter a bit of data that will increase the likelihood that offers and ads are interesting? Each person can -- and should -- decide for the themselves what to make public, but the answer isn't always necessarily no.

How Codecademy gets your email

image

Here they teach you how to use the "length" method by measuring your email address. Sneaky. I like it.

image

Even if you don't given them an address, they re-prompt you to enter your email, but it doesn't come across as pushy because you're taking a test.

I thought that this was pretty subtle. Because of the context, people who would ordinarily be sensitive to giving up their email might not even notice. Why? Because they want to answer the question correctly. They don't want the site to judge them for having entered something wrong, so they do as they're told.

Is Codecademy collecting emails this way? I have no way to be sure, but they'd be silly not to.

How to drag rewind and fast-forward into the 21st century

This article originally appeared on earthli News and has been cross-posted here.


The most difficult technical problems to solve are the ones that you don't notice. The workflow and tools to which you've become accustomed are terrible, but they're so ingrained that you might actually find yourself unthinkingly defending them because that's just how it has to be.

Below I take a shot at designing a better user experience for a common feature: rewinding or fast-forwarding a video recorded on a DVR.

Why is your DVR's fast-forwarding feature stuck in the past?

Fast-forwarding and rewinding digital movies is one of those things.

Many people have DVRs now -- provided, often enough, by the cable company itself -- but they often function as if customers were still juggling tapes instead of switching between files on a hard drive. While there is no technical hurdle to making this process better, I acknowledge that there are probably very important albeit tediously prosaic advertising reasons for keeping fast-forwarding not just primitive, but almost deliberately broken.

Despite the strong likelihood that this feature will not be improved for the reasons stated above (i.e. that the exorbitant monthly fee that you pay for your content will continue to be supplemented by advertising revenue generated by your captive eyeballs), it would still be fun to imagine how we could make this feature better.

Use cases

The most obvious use case for fast-forwarding is to skip commercials in recorded content: that's just reality. Though the cable companies and networks would dearly love for everyone to take their medicine and watch all of their advertisements, users would dearly love to just watch their content without the ads. That is often the reason that they recorded the content in the first place.

Another use case is to scrub forward in longer sports events, like cycling or the Olympics. The user generally doesn't want to watch six hours; instead, the user would like to skip forward 2.5 hours, watch 15 minutes, skip another hour, watch 30 minutes, skip another hour and watch the rest, all the while skipping commercials in between. Often the user doesn't even know how far they want to skip; they need to see the content at various intervals in order to see where to stop. This is currently achieved by just scrubbing through all the content sequentially.

This is all not only a tedious amount of work but also takes much longer than necessary: even at the top speed, the fast-forward feature takes long minutes to skip two hours of content. This is ridiculous, especially when most of us have seen it work at least marginally better on a computer, where one can skip large chunks of content and reliably jump to a specific position in the recording. The system described below could improve the experience for computer-based media players as well.

What's the problem?

Fast-forwarding is a pain because, while you'd like to jump forward as quickly as possible, you have to be fast enough to stop it before it's gone too far. This is old-school technology from the days of the VCR when there was only one read-head per device. Now there's a digital file that the machine can easily read and render thumbnails from anywhere in the data stream.

My media box from UPC Cablecom offers the standard controls for scrubbing: play, pause, fast-forward, rewind. When you press rewind or fast-forward, it moves between five speeds, skipping forward or backward faster with each level. When you've got it on 5 of 5, you skip commercials or content very quickly, but you're also extremely likely to skip over content you wanted to watch.

The standard pattern is to fly forward, slam on the brakes, then backtrack slowly, overshoot again -- but not by as much -- and then finally position the read-head about where you want it, watching the final 20 seconds of commercials or station identification that you couldn't avoid until you finally get to the content you were looking for.

There has to be a better way of doing this.

Making it better

The idea of five speeds is fine, but we should be able to take the twitch-gamer component out of the experience. And this is coming from someone who used to be a pretty dedicated gamer; I can't imagine what this system feels like to someone unaccustomed to technology. They probably just put it on the slow speed -- or don't bother fast-forwarding at all.

What about a solution that works like this: instead of changing speed immediately, pressing rewind or fast-forward pauses the stream and switches to a scrubbing mode. The scrubbing mode is displayed as a screen of tiles -- say 5x5 -- each tile representing a screenshot/thumbnail from the stream that you're watching.

The thumbnails are chosen in the following manner. If you pressed fast-forward, the thumbnail for your current position is shown in the upper left-hand corner. Subsequent tiles are chosen at 5-second intervals going forward in the stream. Pressing the fast-forward again increases the level -- as before -- but, instead of speeding through the stream, it simply chooses new thumbnails, this time at 10-second intervals. Press again to switch to 30-second, then 1-minute, then 5-minute intervals. At the top "speed" the bottom right-hand corner shows a thumbnail 24 x 5 minutes forward in the stream.

Rewind has the same behavior, except that the current position is shown in the bottom right-hand corner and thumbnails proceed from right-to-left, bottom-to-top to show the user data in the stream before that position.

Once the user is on this screen, he or she can use the cursor to select the desired thumbnail and refocus the screen on that one by clicking OK. In this way, the user can quickly and reliably use the fast-forward or rewind buttons to switch the granularity to "home in" in on a particular scene. All without any stress, missteps or a lot of senseless back-and-forth scrubbing. And all without having to watch hardly anything -- a few seconds at most -- that the user doesn't want to watch.

When the right scene is selected (to within 5 seconds), the user presses play or pause to continue watching from the newly selected position.

Players like Roku have a "jump back ten seconds" feature that's quite useful, but the system described above makes that sound utterly primitive and limiting.

Going beyond five intervals

It is no longer necessary to have only 5 fixed intervals either. Perhaps the default interval (user-configurable) is 2 seconds, but that's only the center of a scale with 10 steps, so the user can drop down to 1-second or 1/2-second increments as well.

Positioning the current scene in scrubber mode

The system described above moves the default location of the current scene, depending on whether the user pressed rewind (bottom-right corner) or fast forward (top-left corner). Another approach would be to ignore which button was pressed and to always show the current scene in the center of the grid, with thumbnails showing history as well as future in the recording. Further presses of rewind and fast forward increase or decrease the amount of time represented by each thumbnail.

Rendering thumbnails

If the software takes time to render the thumbnails, it can do it asynchronously, rendering thumbnails to screen as they become available. Showing the time under the thumbnail would be massively helpful even without a thumbnail. The user could easily jump ahead 4 minutes without any adrenalin at all.

This should be a huge problem, though. Whenever the user opens a recording, the software can proactively cache thumbnails based on expected usage or default settings.