Implementing a framework validator
To proper validate the project against the functionality supported by a
target framework, framework validators are used. Framework validators
are classes deriving from
SD.LLBLGen.Pro.ApplicationCore.Extensibility.FrameworkValidatorBase
,
which is an abstract class in the ApplicationCore assembly. The
validator assembly's location and filename is specified in the
framework's .framework
file.
During the second stage of the project validation process, the framework
specific validator as specified in the .framework
file of the target
framework of the project is instantiated and asked to verify the
project. This is done by calling the validator's Validate method.
Reporting errors / warnings
The LLBLGen Pro designer supports an error / warning messaging system.
All errors and warnings are reported as messages to the central message
dispatcher. The messages are distributed to subscribers, among them the
Error List pane in the LLBLGen Pro designer. The FrameworkValidatorBase
class contains several methods to make it easy to construct and send
error, warning and normal messages. Normal messages end up in the
Application Output pane. An error or warning message is called a
Correctable message. A correctable message can contain suggestions or
steps.
After a message has been constructed and is ready to be posted, call the
FrameworkValidatorBase
method DispatchCorrectableMessage()
. When you
detect an error and report an error message, your validate method has to
return false. This signals to the validate control logic that at least
an error has been posted and the process has to be stopped at the end of
the validation stage and can't proceed.
Correctable message corrections are added by calling the AddCorrection
method on the CorrectableMessage created. A correction can be a lambda
containing correction, or a go location containing correction. A step in
a list of suggestions is also added with AddCorrection
, but doesn't
contain any lamdba/go location object. In general corrections are
lambda's/go location corrections so the user can directly take action by
clicking the correction in the Errors and Warnings list.
To open an editor, a SourceLocationData
derived object has to be
provided to the RaiseGoLocationRequested
method of the message
dispatcher (see example below). Main objects in a project, like entity
definitions, provide such a go location object themselves. Other
objects, like relationships require an instantiation of their source
location data subclass, which are available in the namespace
SD.LLBLGen.Pro.ApplicationCore.MessageReporting.SourceLocationDataClasses
in the ApplicationCore assembly.
Example
The following example is a validation provided by the
FrameworkValidatorBase class itself. It illustrates a simple validation
and how an error message is posted as well as how a correction is added
to the error message. This correction opens the entity editor of the
entity which contains the error. The AsFormatted
extension method is
found in the BCLExtensions assembly shipped with LLBLGen Pro and which
is licensed to LLBLGen Pro licensees under the BSD license.
/// <summary>
/// Reports an error if the subElement name specified is equal to the name of the containingElement specified
/// </summary>
/// <param name="subElementName">Name of the sub element.</param>
/// <param name="containingElement">The containing element.</param>
/// <param name="error">if set to <c>true</c> a conflict is reported as an error, otherwise as a warning.</param>
/// <returns>
/// true if no error was dispatched, false otherwise
/// </returns>
protected virtual bool ReportSubElementNameEqualToContainingElementNameAsCorrectableMessage(
string subElementName, GroupableModelElement containingElement, bool error)
{
bool toReturn = true;
if(string.IsNullOrEmpty(subElementName) || (containingElement == null))
{
return true;
}
if(subElementName.ToLowerInvariant() == containingElement.Name.ToLowerInvariant())
{
toReturn = !error;
var message = this.CreateCorrectableMessage(error, true,
"The {0} '{1}' contains field '{2}', however the field has the same name as the {0}, something which isn't supported by the target framework.",
containingElement.GetElementNameForErrorReporting(), containingElement.FullName, subElementName);
message.AddCorrection("Open the {0} '{1}' in its editor and change the name of field '{2}' into something else."
.AsFormatted(
containingElement.GetElementNameForErrorReporting(),
containingElement.FullName, subElementName),
1, () => MessageManagerSingleton.GetInstance().RaiseGoLocationRequested(
containingElement.CreateSourceLocationDataObject()));
this.DispatchCorrectableMessage(message);
}
return toReturn;
}