This page shows the source for this entry, with WebCore formatting language tags and attributes highlighted.

Title

v2.0-beta2: Code generation, IOC and configuration

Description

The summary below describes major new features, items of note and breaking changes. The <a href="https://secure.encodo.ch/jira/secure/ReleaseNote.jspa?projectId=10006&version=19704">full list of issues</a> is also available for those with access to the Encodo issue tracker. <h>Highlights</h> In <a href="{app}/view_article.php?id=3128">beta1</a>, we read about changes to configuration, the data driver architecture, DDL commands, and security and access control in web applications. In beta-2, we made the following additional improvements: <ul> Introduced a <b>new generated-code version</b> that avoids all global references and provides a much-improved API for working with metadata. See below for more details. (<a href="https://secure.encodo.ch/jira/browse/QNO-4821">QNO-4821</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-4820">QNO-4820</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-4819">QNO-4819</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-4818">QNO-4818</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-4817">QNO-4817</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-4816">QNO-4816</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-4815">QNO-4815</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-4814">QNO-4814</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-4813">QNO-4813</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-4812">QNO-4812</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-4507">QNO-4507</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-4506">QNO-4506</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-4117">QNO-4117</a>) Continued to update and <b>standardize configuration</b> and execution for applications, as documented in Encodo's configuration library for Quino: <a href="{app}/view_article.php?id=3132">part I</a>, <a href="{app}/view_article.php?id=3138">part II</a> and <a href="{app}/view_article.php?id=3137">part III</a>. (<a href="https://secure.encodo.ch/jira/browse/QNO-4834">QNO-4834</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-4831">QNO-4831</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-4809">QNO-4809</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-4772">QNO-4772</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-4663">QNO-4663</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-4664">QNO-4664</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-4360">QNO-4360</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-4771">QNO-4771</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-4676">QNO-4676</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-4675">QNO-4675</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-4673">QNO-4673</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-3765">QNO-3765</a>) <b>Moved</b> all <b>globals</b> and static classes with global dependencies to the application's <b>IOC container</b>. (<a href="https://secure.encodo.ch/jira/browse/QNO-4791">QNO-4791</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-4792">QNO-4792</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-4790">QNO-4790</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-4784">QNO-4784</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-4782">QNO-4782</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-4778">QNO-4778</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-4787">QNO-4787</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-4774">QNO-4774</a>) <b>Reduce direct dependencies</b> and properties in <c>IApplication</c>, <c>ICoreApplication</c> and <c>IMetaApplication</c>. (<a href="https://secure.encodo.ch/jira/browse/QNO-4789">QNO-4789</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-4788">QNO-4788</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-4786">QNO-4786</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-4785">QNO-4785</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-4671">QNO-4671</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-4669">QNO-4669</a>, , <a href="https://secure.encodo.ch/jira/browse/QNO-4668">QNO-4668</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-4667">QNO-4667</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-4660">QNO-4660</a>) Removed references to GlobalContext and ServiceLocator from the <b>Winforms components</b> (<a href="https://secure.encodo.ch/jira/browse/QNO-4832">QNO-4832</a>) <b>Standardized naming</b> and namespaces to conform to industry, StyleCop and .NET conventions. (<a href="https://secure.encodo.ch/jira/browse/QNO-4807">QNO-4807</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-4806">QNO-4806</a>) Added support for <b>parameterized custom SQL</b> queries with the <c>ICustomCommandBuilder</c>. This was added by customer request, for applications that formulate queries that are beyond what the Quino ORM is currently capable of mapping. A blog post with more detail on how this works is forthcoming. (<a href="https://secure.encodo.ch/jira/browse/QNO-4802">QNO-4802</a>) Further <b>cleanup</b> and consolidation in the <b>data-driver</b> hierarchy. This work was a direct result of Daniel Roth's Bachelor's thesis work in which he integrated NHibernate as an alternative ORM for Quino. (<a href="https://secure.encodo.ch/jira/browse/QNO-4808">QNO-4808</a>; still to do by RTM: <a href="https://secure.encodo.ch/jira/browse/QNO-4749">QNO-4749</a>) <b>Discontinued</b> support for <b><c>DataContract</c></b> and <c>DataMember</c> attributes in metadata and generated code. (<a href="https://secure.encodo.ch/jira/browse/QNO-4823">QNO-4823</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-4826">QNO-4826</a>) </ul> <h>Goodbye, old friends</h> This release addressed some issues that have been bugging us for a while (almost 3 years in one case). <ul> <a href="https://secure.encodo.ch/jira/browse/QNO-3765">QNO-3765</a> (<b>32 months</b>): After a schema migration caused by a DatabaseException on login, restart the application <a href="https://secure.encodo.ch/jira/browse/QNO-4117">QNO-4117</a> (<b>27 months</b>): PreferredType registration for models is not always executed <a href="https://secure.encodo.ch/jira/browse/QNO-4408">QNO-4408</a> (<b>18 months</b>): When access to the remoting server is unauthorized, the web site should respond with an error <a href="https://secure.encodo.ch/jira/browse/QNO-4506">QNO-4506</a> (<b>14 months</b>): The code generator should generate the persistent object and metadata references in separate classes <a href="https://secure.encodo.ch/jira/browse/QNO-4507">QNO-4507</a> (<b>14 months</b>): Business objects for modules should not rely on GlobalContext in generated code </ul> You will not be missed. <h>Breaking changes</h> As we've mentioned before, this release is absolutely merciless in regard to backwards compatibility. Old code is not retained as obsolete <c>Obsolete</c>. Instead, a project upgrading to 2.0 will encounter compile errors. That said, if you arm yourself with a bit of time, ReSharper and the release notes (and possibly keep an Encodo employee on speed-dial), the upgrade is not difficult. It consists mainly of letting ReSharper update namespace references for you. In cases where the update is not so straightforward, we've provided release notes. <h>V1 generated code support</h> One of the few things you'll be able to keep (at least for a minor version or two) is the old-style generated code. We made this concession because, while even a large solution can be upgraded from 1.13.0 to 2.0 relatively painlessly in about an hour (we've converted our own internal projects to test), changing the generated-code format is potentially a much larger change. Again, an upgrade to the generated-code format isn't <i>complicated</i> but it might require more than an hour or two's worth of elbow grease to complete. Therefore, you'll be able to not only retain your old generated code, but the code generator will continue support the old-style code-generation format for further development. Expect the grace period to be relatively short, though. Regardless of whether you elect to keep the old-style generated code, you'll have to do a <i>little</i> bit of extra work just to be able to generate code again. <ol> Manually update a couple of generated files, as shown below. Compile the solution Generate code with the Quino tools </ol> Before you can regenerate, you'll have to manually update your previously generated code in the main model file, as shown below. <h level="3">Previous version</h> <code> static MyModel() { Messages = new InMemoryRecorder(); Loader = new ModelLoader(() => Instance, () => Messages, new MyModelGenerator()); } public static IMetaModel CreateModel(IExtendedRecorder recorder) { if (recorder == null) { throw new ArgumentNullException("recorder"); } var result = Loader.Generator.CreateModel(recorder); result.Configure(); return result; } // More code ... /// <inheritdoc/> protected override void DoConfigure() { base.DoConfigure(); ConfigurePreferredTypes(); ApplyCustomConfiguration(); } </code> <h level="3">Manually updated version</h> <code> static MyModel() { Messages = new InMemoryRecorder(); <del>Loader = new ModelLoader(() => Instance, () => Messages, new MyModelGenerator());</del> } public static IMetaModel CreateModel(IExtendedRecorder recorder) { if (recorder == null) { throw new ArgumentNullException("recorder"); } var result = <del>Loader.Generator</del><hl>(MyModel)new MyModelGenerator()</hl>.CreateModel( <hl>ServiceLocator.Current.GetInstance<iexpressionparser>(), ServiceLocator.Current.GetInstance<imetaexpressionfactory>(), </hl>recorder ); result.Configure<hl>PreferredTypes(); result.ApplyCustomConfiguration();</hl> return result; } <del>/// <inheritdoc/> protected override void DoConfigure() { base.DoConfigure(); ConfigurePreferredTypes(); ApplyCustomConfiguration(); }</del> </code> <h level="3">Integrate into the model builder</h> In the application configuration for the first time you generate code with Quino 2.0, you should use: <code> ModelLoader = MyModel.Loader; <hl>this.UseMetaSimpleInjector(); this.UseModelLoader(MyModel.CreateModel);</hl> </code> After regenerating code, you should use the following for version-2 generated code: <code> <del>ModelLoader = MyModel.Loader;</del> this.UseMetaSimpleInjector(); this.UseModelLoader(MyModel<hl>Extensions</hl>.CreateModel<hl>AndMetadata</hl>); </code> ...and the following for version-1 generated code: <code> <del>ModelLoader = MyModel.Loader;</del> this.UseMetaSimpleInjector(); this.UseModelLoader(MyModel.CreateModel); </code> <h>Still to do by RTM</h> As you can see, we've already done quite a bit of work in beta1 and beta2. We have a few more tasks planned for the feature-complete release candidate for 2.0 <ul> <div>Move the schema-migration <b>metadata table to a module</b>. The Quino schema-migration extracts most of the information it needs from database schema itself. It also stores extra metadata in a special table. This table has been with Quino since before modules were supported (over seven years) and hence was built in a completely custom manner. Moving this support to a Quino metadata module will remove unnecessary implementation and make the migration process more straightforward. (<a href="https://secure.encodo.ch/jira/browse/QNO-4888">QNO-4888</a>) </div> <div><b>Separate collection algorithm</b> from storage/display method in <b><c>IRecorder</c></b> and descendants. The recording/logging library has a very good interface but the implementation for the standard recorders has become too complex as we added support for multi-threading, custom disposal and so on. We want to clean this up to make it easier to extend the library with custom loggers. (<a href="https://secure.encodo.ch/jira/browse/QNO-4888">QNO-4888</a>) </div> <div><b>Split up</b> Encodo and Quino <b>assemblies</b> based on functionality. There are only a very dependencies left to untangle (<a href="https://secure.encodo.ch/jira/browse/QNO-4678">QNO-4678</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-4672">QNO-4672</a>, <a href="https://secure.encodo.ch/jira/browse/QNO-4670">QNO-4670</a>); after that, we'll split up the two main Encodo and Quino assemblies along functional lines. (<a href="https://secure.encodo.ch/jira/browse/QNO-4376">QNO-4376</a>) </div> <div><b>Finish integrating</b> building and publishing <b>NuGet</b> and symbol packages into Quino's release process. And, finally, once we have the assemblies split up to our liking, we'll finalize the Nuget packages for the Quino library and leave the direct-assembly-reference days behind us, ready for Visual Studio 2015. (<a href="https://secure.encodo.ch/jira/browse/QNO-4376">QNO-4376</a>) </div> </ul> That's all we've got for now. See you next month for the next (and, hopefully, final update)!