568 lines
21 KiB
C#
568 lines
21 KiB
C#
|
//---------------------------------------------------------------------
|
||
|
// <copyright file="ClientApiGenerator.cs" company="Microsoft">
|
||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
// </copyright>
|
||
|
//
|
||
|
// @owner [....]
|
||
|
// @backupOwner [....]
|
||
|
//---------------------------------------------------------------------
|
||
|
|
||
|
using System;
|
||
|
using System.CodeDom;
|
||
|
using System.CodeDom.Compiler;
|
||
|
using System.Collections;
|
||
|
using System.Collections.Generic;
|
||
|
using System.Data;
|
||
|
using System.Data.EntityModel.Emitters;
|
||
|
using SOM = System.Data.EntityModel.SchemaObjectModel;
|
||
|
using System.Diagnostics;
|
||
|
using System.Data.Metadata.Edm;
|
||
|
using System.Data.Entity.Design;
|
||
|
using System.IO;
|
||
|
using System.Data.EntityModel.SchemaObjectModel;
|
||
|
using System.Data.Entity.Design.SsdlGenerator;
|
||
|
using System.Linq;
|
||
|
using System.Data.Entity.Design.Common;
|
||
|
using System.Runtime.Versioning;
|
||
|
|
||
|
namespace System.Data.EntityModel
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// Summary description for ClientApiGenerator.
|
||
|
/// </summary>
|
||
|
internal sealed class ClientApiGenerator
|
||
|
{
|
||
|
#region Instance Fields
|
||
|
private string _codeNamespace = null;
|
||
|
private CodeCompileUnit _compileUnit = null;
|
||
|
private bool _isLanguageCaseSensitive = true;
|
||
|
|
||
|
private EdmItemCollection _edmItemCollection = null;
|
||
|
private Schema _sourceSchema = null;
|
||
|
private FixUpCollection _fixUps = null;
|
||
|
private AttributeEmitter _attributeEmitter = null;
|
||
|
EntityClassGenerator _generator;
|
||
|
List<EdmSchemaError> _errors;
|
||
|
TypeReference _typeReference = new TypeReference();
|
||
|
|
||
|
#endregion
|
||
|
|
||
|
#region Public Methods
|
||
|
public ClientApiGenerator(Schema sourceSchema, EdmItemCollection edmItemCollection, EntityClassGenerator generator, List<EdmSchemaError> errors)
|
||
|
{
|
||
|
Debug.Assert(sourceSchema != null, "sourceSchema is null");
|
||
|
Debug.Assert(edmItemCollection != null, "edmItemCollection is null");
|
||
|
Debug.Assert(generator != null, "generator is null");
|
||
|
Debug.Assert(errors != null, "errors is null");
|
||
|
|
||
|
_edmItemCollection = edmItemCollection;
|
||
|
_sourceSchema = sourceSchema;
|
||
|
_generator = generator;
|
||
|
_errors = errors;
|
||
|
_attributeEmitter = new AttributeEmitter(_typeReference);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Parses a source Schema and outputs client-side generated code to
|
||
|
/// the output TextWriter.
|
||
|
/// </summary>
|
||
|
/// <param name="schema">The source Schema</param>
|
||
|
/// <param name="output">The TextWriter in which to write the output</param>
|
||
|
/// <param name="outputUri">The Uri for the output. Can be null.</param>
|
||
|
/// <returns>A list of GeneratorErrors.</returns>
|
||
|
[ResourceExposure(ResourceScope.None)] //No resource is exposed.
|
||
|
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] //For Path.GetTempPath method.
|
||
|
//We use tha path to create a temp file stream which is consistent with the resource consumption of machine.
|
||
|
|
||
|
internal void GenerateCode(LazyTextWriterCreator target, string targetLocation)
|
||
|
{
|
||
|
Debug.Assert(target != null, "target parameter is null");
|
||
|
|
||
|
IndentedTextWriter indentedTextWriter = null;
|
||
|
System.IO.Stream tempFileStream = null;
|
||
|
System.IO.StreamReader reader = null;
|
||
|
System.IO.StreamWriter writer = null;
|
||
|
TempFileCollection tempFiles = null;
|
||
|
try
|
||
|
{
|
||
|
CodeDomProvider provider = null;
|
||
|
switch (Language)
|
||
|
{
|
||
|
case LanguageOption.GenerateCSharpCode:
|
||
|
provider = new Microsoft.CSharp.CSharpCodeProvider();
|
||
|
break;
|
||
|
|
||
|
case LanguageOption.GenerateVBCode:
|
||
|
provider = new Microsoft.VisualBasic.VBCodeProvider();
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
_isLanguageCaseSensitive = (provider.LanguageOptions & LanguageOptions.CaseInsensitive) == 0;
|
||
|
|
||
|
new NamespaceEmitter(this, _codeNamespace, target.TargetFilePath).Emit();
|
||
|
|
||
|
// if there were errors we don't need the output file
|
||
|
if (RealErrorsExist)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (FixUps.Count == 0 || !FixUpCollection.IsLanguageSupported(Language))
|
||
|
{
|
||
|
indentedTextWriter = new IndentedTextWriter(target.GetOrCreateTextWriter(), "\t");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// need to write to a temporary file so we can do fixups...
|
||
|
tempFiles = new TempFileCollection(Path.GetTempPath());
|
||
|
string filename = Path.Combine(tempFiles.TempDir, "EdmCodeGenFixup-" + Guid.NewGuid().ToString() + ".tmp");
|
||
|
tempFiles.AddFile(filename, false);
|
||
|
tempFileStream = new System.IO.FileStream(filename, System.IO.FileMode.CreateNew, System.IO.FileAccess.ReadWrite,
|
||
|
System.IO.FileShare.None);
|
||
|
indentedTextWriter = new IndentedTextWriter(new System.IO.StreamWriter(tempFileStream), "\t");
|
||
|
}
|
||
|
|
||
|
CodeGeneratorOptions styleOptions = new CodeGeneratorOptions();
|
||
|
styleOptions.BracingStyle = "C";
|
||
|
styleOptions.BlankLinesBetweenMembers = false;
|
||
|
styleOptions.VerbatimOrder = true;
|
||
|
provider.GenerateCodeFromCompileUnit(CompileUnit, indentedTextWriter, styleOptions);
|
||
|
|
||
|
// if we wrote to a temp file need to post process the file...
|
||
|
if (tempFileStream != null)
|
||
|
{
|
||
|
indentedTextWriter.Flush();
|
||
|
tempFileStream.Seek(0, System.IO.SeekOrigin.Begin);
|
||
|
reader = new System.IO.StreamReader(tempFileStream);
|
||
|
FixUps.Do(reader, target.GetOrCreateTextWriter(), Language, SourceObjectNamespaceName != string.Empty);
|
||
|
}
|
||
|
}
|
||
|
catch (System.UnauthorizedAccessException ex)
|
||
|
{
|
||
|
AddError(ModelBuilderErrorCode.SecurityError, EdmSchemaErrorSeverity.Error, ex);
|
||
|
}
|
||
|
catch (System.IO.FileNotFoundException ex)
|
||
|
{
|
||
|
AddError(ModelBuilderErrorCode.FileNotFound, EdmSchemaErrorSeverity.Error, ex);
|
||
|
}
|
||
|
catch (System.Security.SecurityException ex)
|
||
|
{
|
||
|
AddError(ModelBuilderErrorCode.SecurityError, EdmSchemaErrorSeverity.Error, ex);
|
||
|
}
|
||
|
catch (System.IO.DirectoryNotFoundException ex)
|
||
|
{
|
||
|
AddError(ModelBuilderErrorCode.DirectoryNotFound, EdmSchemaErrorSeverity.Error, ex);
|
||
|
}
|
||
|
catch (System.IO.IOException ex)
|
||
|
{
|
||
|
AddError(ModelBuilderErrorCode.IOException, EdmSchemaErrorSeverity.Error, ex);
|
||
|
}
|
||
|
finally
|
||
|
{
|
||
|
if (indentedTextWriter != null)
|
||
|
{
|
||
|
indentedTextWriter.Close();
|
||
|
}
|
||
|
if (tempFileStream != null)
|
||
|
{
|
||
|
tempFileStream.Close();
|
||
|
}
|
||
|
if (tempFiles != null)
|
||
|
{
|
||
|
tempFiles.Delete();
|
||
|
((IDisposable)tempFiles).Dispose();
|
||
|
}
|
||
|
if (reader != null)
|
||
|
{
|
||
|
reader.Close();
|
||
|
}
|
||
|
if (writer != null)
|
||
|
{
|
||
|
writer.Close();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Verification code invoked for types
|
||
|
/// </summary>
|
||
|
/// <param name="item">The type being generated</param>
|
||
|
internal void VerifyLanguageCaseSensitiveCompatibilityForType(GlobalItem item)
|
||
|
{
|
||
|
if (_isLanguageCaseSensitive)
|
||
|
{
|
||
|
return; // no validation necessary
|
||
|
}
|
||
|
|
||
|
try
|
||
|
{
|
||
|
_edmItemCollection.GetItem<GlobalItem>(
|
||
|
item.Identity,
|
||
|
true // ignore case
|
||
|
);
|
||
|
}
|
||
|
catch (InvalidOperationException)
|
||
|
{
|
||
|
AddError(Strings.ItemExistsWithDifferentCase(item.BuiltInTypeKind.ToString(), item.Identity), ModelBuilderErrorCode.IncompatibleSettingForCaseSensitiveOption,
|
||
|
EdmSchemaErrorSeverity.Error, item.Identity);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/// <summary>
|
||
|
/// Verification code invoked for properties
|
||
|
/// </summary>
|
||
|
/// <param name="item">The property or navigation property being generated</param>
|
||
|
internal void VerifyLanguageCaseSensitiveCompatibilityForProperty(EdmMember item)
|
||
|
{
|
||
|
if (_isLanguageCaseSensitive)
|
||
|
{
|
||
|
return; // no validation necessary
|
||
|
}
|
||
|
|
||
|
Debug.Assert(item != null);
|
||
|
|
||
|
ReadOnlyMetadataCollection<EdmMember> members = item.DeclaringType.Members;
|
||
|
|
||
|
HashSet<string> set = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||
|
|
||
|
foreach (EdmMember member in members)
|
||
|
{
|
||
|
if (set.Contains(member.Identity) &&
|
||
|
item.Identity.Equals(member.Identity, StringComparison.OrdinalIgnoreCase))
|
||
|
{
|
||
|
AddError(Strings.PropertyExistsWithDifferentCase(item.Identity), ModelBuilderErrorCode.IncompatibleSettingForCaseSensitiveOption,
|
||
|
EdmSchemaErrorSeverity.Error, item.DeclaringType.FullName, item.Identity);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
set.Add(member.Identity);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Verification code invoked for entity sets
|
||
|
/// </summary>
|
||
|
/// <param name="item">The entity container being generated</param>
|
||
|
internal void VerifyLanguageCaseSensitiveCompatibilityForEntitySet(System.Data.Metadata.Edm.EntityContainer item)
|
||
|
{
|
||
|
if (_isLanguageCaseSensitive)
|
||
|
{
|
||
|
return; // no validation necessary
|
||
|
}
|
||
|
|
||
|
Debug.Assert(item != null);
|
||
|
|
||
|
HashSet<string> set = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||
|
|
||
|
foreach (EntitySetBase entitySetBase in item.BaseEntitySets)
|
||
|
{
|
||
|
if (MetadataUtil.IsEntitySet(entitySetBase))
|
||
|
{
|
||
|
EntitySet entitySet = (EntitySet)entitySetBase;
|
||
|
if (set.Contains(entitySet.Identity))
|
||
|
{
|
||
|
AddError(ModelBuilderErrorCode.IncompatibleSettingForCaseSensitiveOption,
|
||
|
EdmSchemaErrorSeverity.Error, new InvalidOperationException(Strings.EntitySetExistsWithDifferentCase(entitySet.Identity)),
|
||
|
item.Name);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
set.Add(entitySet.Identity);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal IEnumerable<EdmType> GetDirectSubTypes(EdmType edmType)
|
||
|
{
|
||
|
return _edmItemCollection.GetItems<EdmType>().Where(b => b.BaseType == edmType);
|
||
|
}
|
||
|
|
||
|
private static System.Data.EntityModel.SchemaObjectModel.SchemaElement GetSchemaElement(
|
||
|
System.Data.EntityModel.SchemaObjectModel.Schema schema, string itemIdentity)
|
||
|
{
|
||
|
List<System.Data.EntityModel.SchemaObjectModel.SchemaType> schemaTypes =
|
||
|
schema.SchemaTypes.Where(p => p.Identity == itemIdentity).ToList();
|
||
|
if (null != schemaTypes && schemaTypes.Count > 0)
|
||
|
{
|
||
|
return (System.Data.EntityModel.SchemaObjectModel.SchemaElement)schemaTypes.First();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
internal static void GetElementLocationInfo(System.Data.EntityModel.SchemaObjectModel.Schema schema, string itemIdentity, out int lineNumber, out int linePosition)
|
||
|
{
|
||
|
System.Data.EntityModel.SchemaObjectModel.SchemaElement element = GetSchemaElement(schema, itemIdentity);
|
||
|
|
||
|
if(null != element)
|
||
|
{
|
||
|
lineNumber = element.LineNumber;
|
||
|
linePosition = element.LinePosition;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
lineNumber = linePosition = -1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal static void GetElementLocationInfo(System.Data.EntityModel.SchemaObjectModel.Schema schema, string parentIdentity, string itemIdentity, out int lineNumber, out int linePosition)
|
||
|
{
|
||
|
lineNumber = linePosition = -1;
|
||
|
|
||
|
System.Data.EntityModel.SchemaObjectModel.SchemaElement element = GetSchemaElement(schema, parentIdentity);
|
||
|
System.Data.EntityModel.SchemaObjectModel.StructuredType elementWithProperty =
|
||
|
element as System.Data.EntityModel.SchemaObjectModel.StructuredType;
|
||
|
|
||
|
if (null != elementWithProperty && elementWithProperty.Properties.ContainsKey(itemIdentity))
|
||
|
{
|
||
|
lineNumber = elementWithProperty.Properties[itemIdentity].LineNumber;
|
||
|
linePosition = elementWithProperty.Properties[itemIdentity].LinePosition;
|
||
|
}
|
||
|
else if( null != element)
|
||
|
{
|
||
|
lineNumber = element.LineNumber;
|
||
|
linePosition = element.LinePosition;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
|
||
|
#region Internal Properties
|
||
|
|
||
|
internal LanguageOption Language
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return _generator.LanguageOption;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal TypeReference TypeReference
|
||
|
{
|
||
|
get { return _typeReference; }
|
||
|
}
|
||
|
|
||
|
internal CodeCompileUnit CompileUnit
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
if (_compileUnit == null)
|
||
|
_compileUnit = new CodeCompileUnit();
|
||
|
|
||
|
return _compileUnit;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void AddError(string message, ModelBuilderErrorCode errorCode, EdmSchemaErrorSeverity severity)
|
||
|
{
|
||
|
_errors.Add(new EdmSchemaError(message, (int)errorCode, severity));
|
||
|
}
|
||
|
|
||
|
public void AddError(ModelBuilderErrorCode errorCode, EdmSchemaErrorSeverity severity, Exception ex)
|
||
|
{
|
||
|
_errors.Add(new EdmSchemaError(ex.Message, (int)errorCode, severity, ex));
|
||
|
}
|
||
|
|
||
|
internal void AddError(string message, ModelBuilderErrorCode errorCode, EdmSchemaErrorSeverity severity, Exception ex)
|
||
|
{
|
||
|
_errors.Add(new EdmSchemaError(message, (int)errorCode, severity, ex));
|
||
|
}
|
||
|
|
||
|
internal void AddError(ModelBuilderErrorCode errorCode, EdmSchemaErrorSeverity severity, Exception ex, string itemIdentity)
|
||
|
{
|
||
|
int lineNumber, linePosition;
|
||
|
ClientApiGenerator.GetElementLocationInfo(this._sourceSchema, itemIdentity, out lineNumber, out linePosition);
|
||
|
|
||
|
_errors.Add(new EdmSchemaError(ex.Message, (int)errorCode, severity, this._sourceSchema.Location, lineNumber, linePosition, ex));
|
||
|
}
|
||
|
|
||
|
internal void AddError(string message, ModelBuilderErrorCode errorCode, EdmSchemaErrorSeverity severity, string itemIdentity)
|
||
|
{
|
||
|
int lineNumber, linePosition;
|
||
|
ClientApiGenerator.GetElementLocationInfo(this._sourceSchema, itemIdentity, out lineNumber, out linePosition);
|
||
|
|
||
|
_errors.Add(new EdmSchemaError(message, (int)errorCode, severity, this._sourceSchema.Location, lineNumber, linePosition));
|
||
|
}
|
||
|
|
||
|
internal void AddError(string message, ModelBuilderErrorCode errorCode, EdmSchemaErrorSeverity severity, string parentIdentity, string itemIdentity)
|
||
|
{
|
||
|
int lineNumber, linePosition;
|
||
|
ClientApiGenerator.GetElementLocationInfo(this._sourceSchema, parentIdentity, itemIdentity, out lineNumber, out linePosition);
|
||
|
|
||
|
_errors.Add(new EdmSchemaError(message, (int)errorCode, severity, this._sourceSchema.Location, lineNumber, linePosition));
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Check collection for any real errors (Severity != Warning)
|
||
|
/// </summary>
|
||
|
public bool RealErrorsExist
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
foreach (EdmSchemaError error in _errors)
|
||
|
{
|
||
|
if (error.Severity != EdmSchemaErrorSeverity.Warning)
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public IEnumerable<GlobalItem> GetSourceTypes()
|
||
|
{
|
||
|
foreach (SOM.SchemaType type in _sourceSchema.SchemaTypes)
|
||
|
{
|
||
|
if (type is SOM.ModelFunction)
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
yield return _edmItemCollection.GetItem<GlobalItem>(type.Identity);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public CodeTypeReference GetFullyQualifiedTypeReference(EdmType type)
|
||
|
{
|
||
|
string fullObjectName = CreateFullName(GetObjectNamespace(type.NamespaceName), type.Name);
|
||
|
return TypeReference.FromString(fullObjectName);
|
||
|
}
|
||
|
|
||
|
public CodeTypeReference GetFullyQualifiedTypeReference(EdmType type, bool addGlobalQualifier)
|
||
|
{
|
||
|
string fullObjectName = CreateFullName(GetObjectNamespace(type.NamespaceName), type.Name);
|
||
|
return TypeReference.FromString(fullObjectName, addGlobalQualifier);
|
||
|
}
|
||
|
|
||
|
private string CreateFullName(string namespaceName, string name)
|
||
|
{
|
||
|
if (string.IsNullOrEmpty(namespaceName))
|
||
|
{
|
||
|
return name;
|
||
|
}
|
||
|
|
||
|
return namespaceName + "." + name;
|
||
|
}
|
||
|
|
||
|
public CodeTypeReference GetLeastPossibleQualifiedTypeReference(EdmType type)
|
||
|
{
|
||
|
string typeRef;
|
||
|
|
||
|
if (type.BuiltInTypeKind == BuiltInTypeKind.PrimitiveType)
|
||
|
{
|
||
|
return type.ClrType.IsValueType ? TypeReference.NullableForType(type.ClrType) : TypeReference.ForType(type.ClrType);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (type.NamespaceName == SourceEdmNamespaceName)
|
||
|
{
|
||
|
// we are already generating in this namespace, no need to qualify it
|
||
|
typeRef = type.Name;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
typeRef = CreateFullName(GetObjectNamespace(type.NamespaceName), type.Name);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return TypeReference.FromString(typeRef);
|
||
|
}
|
||
|
|
||
|
public string SourceEdmNamespaceName
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return _sourceSchema.Namespace;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public string SourceObjectNamespaceName
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return GetObjectNamespace(SourceEdmNamespaceName);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private string GetObjectNamespace(string csdlNamespaceName)
|
||
|
{
|
||
|
Debug.Assert(csdlNamespaceName != null, "csdlNamespaceName is null");
|
||
|
|
||
|
string objectNamespace;
|
||
|
if (_generator.EdmToObjectNamespaceMap.TryGetObjectNamespace(csdlNamespaceName, out objectNamespace))
|
||
|
{
|
||
|
return objectNamespace;
|
||
|
}
|
||
|
|
||
|
return csdlNamespaceName;
|
||
|
}
|
||
|
|
||
|
|
||
|
/// <summary>
|
||
|
///
|
||
|
/// </summary>
|
||
|
/// <value></value>
|
||
|
internal FixUpCollection FixUps
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
if (_fixUps == null)
|
||
|
_fixUps = new FixUpCollection();
|
||
|
|
||
|
return _fixUps;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal AttributeEmitter AttributeEmitter
|
||
|
{
|
||
|
get { return _attributeEmitter; }
|
||
|
}
|
||
|
|
||
|
internal bool IsLanguageCaseSensitive
|
||
|
{
|
||
|
get { return _isLanguageCaseSensitive; }
|
||
|
}
|
||
|
|
||
|
internal StringComparison LanguageAppropriateStringComparer
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
if (IsLanguageCaseSensitive)
|
||
|
{
|
||
|
return StringComparison.Ordinal;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return StringComparison.OrdinalIgnoreCase;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Helper method that raises the TypeGenerated event
|
||
|
/// </summary>
|
||
|
/// <param name="eventArgs">The event arguments passed to the subscriber</param>
|
||
|
internal void RaiseTypeGeneratedEvent(TypeGeneratedEventArgs eventArgs)
|
||
|
{
|
||
|
_generator.RaiseTypeGeneratedEvent(eventArgs);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Helper method that raises the PropertyGenerated event
|
||
|
/// </summary>
|
||
|
/// <param name="eventArgs">The event arguments passed to the subscriber</param>
|
||
|
internal void RaisePropertyGeneratedEvent(PropertyGeneratedEventArgs eventArgs)
|
||
|
{
|
||
|
_generator.RaisePropertyGeneratedEvent(eventArgs);
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
|
||
|
}
|
||
|
}
|