v2.0: Logging, Dependencies, New Assemblies & Nuget

Published by Marco on

Updated by Marco on

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

In the beta1 and beta2 release notes, we read about changes to configuration, dependency reduction, the data driver architecture, DDL commands, security and access control in web applications and a new code-generation format.

In 2.0 final—which was actually released internally on November 13th, 2015 (a Friday)—we made the following additional improvements:

These notes are being published for completeness and documentation. The first publicly available release of Quino 2.x will be 2.1 or higher (release notes coming soon).

Breaking changes

 A big project will have a lot of errors (over 12,000!)As we’ve mentioned before, this release is absolutely merciless in regard to backwards compatibility. Old code is not retained as Obsolete. Instead, a project upgrading to 2.0 will encounter compile errors.

The following notes serve as an incomplete guide that will help you upgrade a Quino-based product.

As I wrote in the release notes for beta1 and beta2, 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.

Global Search/Replace

Instead of going through the errors (example shown to the right) one by one, you can take care of a lot of errors with the following search/replace pairs.

  • Encodo.Quino.Data.Persistence => Encodo.Quino.Data
  • IMetaApplication => IApplication
  • ICoreApplication => IApplication
  • GetServiceLocator() => GetServices()
  • MetaMethodTools.GetInstance => DataMetaMethodExtensions.GetInstance
  • application.ServiceLocator.GetInstance => application.GetInstance
  • Application.ServiceLocator.GetInstance => Application.GetInstance
  • application.ServiceLocator => application.GetServices()
  • Application.ServiceLocator => Application.GetServices()
  • application.Recorder => application.GetLogger()
  • Application.Recorder => Application.GetLogger()
  • session.GetRecorder() => session.GetLogger()
  • Session.GetRecorder() => Session.GetLogger()
  • Session.Application.Recorder => Session.GetLogger()
  • FileTools.Canonicalize() => PathTools.Normalize()
  • application.Messages => application.GetMessageList()
  • Application.Messages => Application.GetMessageList()
  • ServiceLocator.GetInstance => Application.GetInstance
  • MetaLayoutTools => LayoutConstants
  • GlobalContext.Instance.Application.Configuration.Model => GlobalContext.Instance.Application.GetModel()
  • IMessageRecorder => ILogger
  • GetUseReleaseSettings() => IsInReleaseMode()
  • ReportToolsDX => ReportDxExtensions

Although you can’t just search/replace everything, it gets you a long way.

Model-Building Fixes

These replacement pairs, while not recommended for global search/replace, are a handy guide for how the API has generally changed.

  • *Generator => *Builder
  • SetUpForModule => CreateModule
  • Builder.SetElementVisibility(prop, true) => prop.Show()
  • Builder.SetElementVisibility(prop, false) => prop.Hide()
  • Builder.SetElementControlIdentifier(prop, ControlIdentifiers => prop.SetInputControl(ControlIdentifiers
  • Builder.SetPropertyHeightInPixels(prop, 200); => prop.SetHeightInPixels(200);

Constructing a module has also changed. Instead of using the following syntax,

var module = Builder.SetUpForModule<AuditModule>(Name, "ApexClearing.Alps.Core", Name, true);

Replace it with the following direct replacement,

var module = Builder.CreateModule(Name, "ApexClearing.Alps.Core", Name);

Or use this replacement, with the recommended style for the v2 format (no more class prefix for generated classes and a standard namespace):

var module = Builder.CreateModule(Name, typeof(AuditModuleBuilder).GetParentNamespace());

Standard Modules (e.g. Reporting, Security, etc.)

Because of how the module class-names have changed, the standard module ORM classes all have different names. The formula is that the ORM class-name is no longer prepended its module name.

  • ReportsReportDefinition => ReportDefinition
  • SecurityUser => User
  • And so on…

Furthermore, all modules have been converted to use the v2 code-generation format, which has the metadata separate from the ORM object. Therefore, instead of referencing metadata using the ORM class-name as the base, you use the module name as the base.

  • ReportReportDefinition.Fields.Name => ReportModule.ReportDefinition.Name.Identifier
  • ReportReportDefinition.MetaProperties.Name => ReportModule.ReportDefinition.Name
  • ReportReportDefinition.Metadata => ReportModule.ReportDefinition.Metadata
  • And so on…

There’s an upcoming article that will show more examples of the improved flexibility and capabilities that come with the v2-metadata.

Action names

The standard action names have moved as well.

  • ActionNames => ApplicationActionNames
  • MetaActionNames => MetaApplicationActionNames

Any other, more rarely used action names have been moved back to the actions themselves, so for example

SaveApplicationSettingsAction.ActionName

If you created any actions of your own, then the API there has changed as well. As previously documented in API Design: To Generic or not Generic? (Part II), instead of overriding the following method,

protected override int DoExecute(IApplication application, ConfigurationOptions options, int currentResult)
{
  base.DoExecute(application, options, currentResult);
}

you instead override in the following way,

public override void Execute()
{
  base.Execute();
}

Using NuGet

If you’re already using Visual Studio 2015, then the NuGet UI is a good choice for managing packages. If you’re still on Visual Studio 2013, then the UI there is pretty flaky and we recommend using the console.

The examples below assume that you have configured a source called “Local Quino” (e.g. a local folder that holds the nupkg files for Quino).

install-package Quino.Data.PostgreSql.Testing -ProjectName Punchclock.Core.Tests -Source "Local Quino"
install-package Quino.Server -ProjectName Punchclock.Server -Source "Local Quino"
install-package Quino.Console -ProjectName Punchclock.Server -Source "Local Quino"
install-package Quino.Web -ProjectName Punchclock.Web.API -Source "Local Quino"

Debugging Support

We recommend using Visual Studio 2015 if at all possible. Visual Studio 2013 is also supported, but we have all migrated to 2015 and our knowhow about 2013 and its debugging idiosyncrasies will deteriorate with time.

These are just brief points of interest to get you set up. As with the NuGet support, these instructions are subject to change as we gain more experience with debugging with packages as well.

  • Hook up to a working symbol-source server (e.g. TeamCity)
  • Get the local sources for your version
  • If you don’t have a source server or it’s flaky, then get the PDBs for the Quino version you’re using (provided in Quino.zip as part of the package release)
  • Add the path to the PDBs to your list of symbol sources in the VS debugging options
  • Tell Visual Studio where the sources are when it asks during debugging
  • Tell R# how to map from the source folder (c:\BuildAgent\work\9a1bb0adebb73b1f for Quino 2.0.0-1765) to the location of your sources

Quino packages are no different than any other NuGet packages. We provide both standard packages as well as packages with symbols and sources. Any complications you encounter with them are due to the whole NuGet experience still being a bit in-flux in the .NET world.

An upcoming post will provide more detail and examples.

Creating Nuget Packages

We generally use our continuous integration server to create packages, but you can also create packages locally (it’s up to you to make sure the version number makes sense, so be careful). These instructions are approximate and are subject to change. I provide them here to give you an idea of how packages are created. If they don’t work, please contact Encodo for help.

  • Open PowerShell
  • Change to the %QUINO_ROOT%\src directory
  • Run nant build pack to build Quino and packages
  • Set up a local NuGet Source name “Local Quino” to %QUINO_ROOT%\nuget (one-time only)
  • Change to the directory where your Quino packages are installed for your solution.
  • Delete all of the Encodo/Quino packages
  • Execute nant nuget from your project directory to get the latest Quino build from your local folder