/// <summary> /// Génération des constantes statiques. /// </summary> /// <param name="w">Writer.</param> /// <param name="item">La classe générée.</param> private void GenerateConstPropertiesClass(CSharpWriter w, ModelClass item) { int nbConstValues = item.ConstValues.Count; if (nbConstValues != 0) { w.WriteLine(); w.WriteLine("#pragma warning disable SA1402"); w.WriteLine(); w.WriteSummary(1, $"Type des valeurs pour {item.Name}"); w.WriteLine(1, $"public sealed class {item.Name}Code : TypeSafeEnum {{"); w.WriteLine(); w.WriteLine(2, $"private readonly Dictionary<string, {item.Name}Code> Instance = new Dictionary<string, {item.Name}Code>();"); w.WriteLine(); w.WriteSummary(2, "Constructeur"); w.WriteParam("value", "Valeur"); w.WriteLine(2, $"public {item.Name}Code(string value)"); w.WriteLine(3, ": base(value) {"); w.WriteLine(3, "Instance[value] = this;"); w.WriteLine(2, "}"); w.WriteLine(); w.WriteLine(2, $"public explicit operator {item.Name}Code(string value) {{"); w.WriteLine(3, $"System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(typeof({item.Name}).TypeHandle);"); w.WriteLine(3, "if (Instance.TryGetValue(value, out var result)) {"); w.WriteLine(4, "return result;"); w.WriteLine(3, "} else {"); w.WriteLine(4, "throw new InvalidCastException();"); w.WriteLine(3, "}"); w.WriteLine(2, "}"); w.WriteLine(1, "}"); } }
/// <summary> /// Génère les méthodes d'extensibilité. /// </summary> /// <param name="w">Writer.</param> /// <param name="item">Classe générée.</param> private void GenerateExtensibilityMethods(CSharpWriter w, ModelClass item) { w.WriteLine(); w.WriteSummary(2, "Methode d'extensibilité possible pour les constructeurs."); w.WriteLine(2, "partial void OnCreated();"); w.WriteLine(); w.WriteSummary(2, "Methode d'extensibilité possible pour les constructeurs par recopie."); w.WriteParam("bean", "Source."); w.WriteLine(2, $"partial void OnCreated({item.Name} bean);"); }
/// <summary> /// Génère le constructeur par défaut. /// </summary> /// <param name="w">Writer.</param> /// <param name="item">Classe générée.</param> private void GenerateDefaultConstructor(CSharpWriter w, ModelClass item) { w.WriteSummary(2, "Constructeur."); w.WriteLine(2, $@"public {item.Name}()"); if (item.ParentClass != null) { w.WriteLine(3, ": base()"); } w.WriteLine(2, "{"); if (item.NeedsInitialization) { foreach (var property in item.PropertyList.Where(p => !p.IsPrimitive && !p.IsCollection)) { w.WriteLine(3, LoadPropertyInit(property.Name, property.DataType)); } foreach (var property in item.PropertyList.Where(p => p.IsCollection)) { w.WriteLine(3, LoadPropertyInit(property.Name, "List<" + LoadInnerDataType(property.DataType) + ">")); } w.WriteLine(); } w.WriteLine(3, "OnCreated();"); w.WriteLine(2, "}"); }
/// <summary> /// Génère le constructeur par recopie d'un type base. /// </summary> /// <param name="w">Writer.</param> /// <param name="item">Classe générée.</param> private void GenerateBaseCopyConstructor(CSharpWriter w, ModelClass item) { w.WriteLine(); w.WriteSummary(2, "Constructeur par base class."); w.WriteParam("bean", "Source."); w.WriteLine(2, "public " + item.Name + "(" + item.ParentClass.Name + " bean)"); w.WriteLine(3, ": base(bean)"); w.WriteLine(2, "{"); w.WriteLine(3, "OnCreated();"); w.WriteLine(2, "}"); }
/// <summary> /// Méthode générant le code d'une classe. /// </summary> /// <param name="item">Classe concernée.</param> /// <param name="ns">Namespace.</param> public void Generate(ModelClass item, ModelNamespace ns) { var fileName = Path.Combine(GetDirectoryForModelClass(_parameters.OutputDirectory, item.DataContract.IsPersistent, _rootNamespace, item.Namespace.Name), item.Name + ".cs"); using (var w = new CSharpWriter(fileName)) { Console.WriteLine("Generating class " + ns.Name + "." + item.Name); GenerateUsings(w, item); w.WriteLine(); w.WriteNamespace($"{_rootNamespace}.{ns.Name}"); w.WriteSummary(1, item.Comment); GenerateClassDeclaration(w, item); w.WriteLine("}"); } }
/// <summary> /// Génération des constantes statiques. /// </summary> /// <param name="w">Writer.</param> /// <param name="item">La classe générée.</param> private void GenerateConstProperties(CSharpWriter w, ModelClass item) { int nbConstValues = item.ConstValues.Count; if (nbConstValues != 0) { int i = 0; foreach (string constFieldName in item.ConstValues.Keys.OrderBy(x => x, StringComparer.Ordinal)) { ++i; var valueLibelle = item.ConstValues[constFieldName]; ModelProperty property = null; if (item.Stereotype == Stereotype.Reference) { foreach (var prop in item.PropertyList) { if (prop.IsUnique) { property = prop; break; } } } else { property = ((IList <ModelProperty>)item.PrimaryKey)[0]; } w.WriteSummary(2, valueLibelle.Libelle); if (_parameters.UseTypeSafeConstValues.Value) { w.WriteLine(2, string.Format("public readonly {2}Code {0} = new {2}Code({1});", constFieldName, valueLibelle.Code, item.Name)); } else { w.WriteLine(2, string.Format("public const string {0} = {1};", constFieldName, valueLibelle.Code)); } w.WriteLine(); } } }
/// <summary> /// Génère le constructeur par recopie. /// </summary> /// <param name="w">Writer.</param> /// <param name="item">Classe générée.</param> private void GenerateCopyConstructor(CSharpWriter w, ModelClass item) { w.WriteLine(); w.WriteSummary(2, "Constructeur par recopie."); w.WriteParam("bean", "Source."); if (item.ParentClass != null) { w.WriteLine(2, "public " + item.Name + "(" + item.Name + " bean)"); w.WriteLine(3, ": base(bean)"); w.WriteLine(2, "{"); } else { w.WriteLine(2, "public " + item.Name + "(" + item.Name + " bean)"); w.WriteLine(2, "{"); } w.WriteLine(3, "if (bean == null)"); w.WriteLine(3, "{"); w.WriteLine(4, "throw new ArgumentNullException(nameof(bean));"); w.WriteLine(3, "}"); w.WriteLine(); foreach (var property in item.PropertyList.Where(p => !p.IsPrimitive && !p.IsCollection)) { w.WriteLine(3, property.Name + " = new " + property.DataType + "(bean." + property.Name + ");"); } foreach (var property in item.PropertyList.Where(p => p.IsCollection)) { w.WriteLine(3, property.Name + " = new List<" + LoadInnerDataType(property.DataType) + ">(bean." + property.Name + ");"); } foreach (var property in item.PropertyList.Where(p => p.IsPrimitive)) { w.WriteLine(3, property.Name + " = bean." + property.Name + ";"); } w.WriteLine(); w.WriteLine(3, "OnCreated(bean);"); w.WriteLine(2, "}"); }
/// <summary> /// Génère la propriété concernée. /// </summary> /// <param name="w">Writer.</param> /// <param name="property">La propriété générée.</param> private void GenerateProperty(CSharpWriter w, ModelProperty property) { w.WriteSummary(2, property.Comment); if (!property.Class.IsView && property.IsPersistent && property.DataMember != null && (!_parameters.NoColumnOnAlias.Value || property.Class.Trigram != null)) { if (property.DataDescription.Domain.PersistentDataType.Contains("json")) { w.WriteAttribute(2, "Column", $@"""{property.DataMember.Name}""", $@"TypeName = ""{property.DataDescription.Domain.PersistentDataType}"""); } else { w.WriteAttribute(2, "Column", $@"""{property.DataMember.Name}"""); } } if (property.DataMember.IsRequired && !property.DataDescription.IsPrimaryKey) { w.WriteAttribute(2, "Required"); } if (property.DataDescription != null) { if (!string.IsNullOrEmpty(property.DataDescription.ReferenceType) && !property.DataDescription.ReferenceClass.IsExternal) { w.WriteAttribute(2, "ReferencedType", $"typeof({property.DataDescription.ReferenceClass.Name})"); } if (property.DataDescription.Domain != null) { w.WriteAttribute(2, "Domain", $@"""{property.DataDescription.Domain.Code}"""); if (!string.IsNullOrEmpty(property.DataDescription.Domain.CustomAnnotation)) { w.WriteLine(2, property.DataDescription.Domain.CustomAnnotation); } } } if (property.DataDescription.IsPrimaryKey) { w.WriteAttribute(2, "Key"); if (property.IsIdManuallySet) { w.WriteAttribute(2, "DatabaseGenerated", "DatabaseGeneratedOption.None"); } } else if (property.DefaultValue != null) { w.WriteAttribute(2, "DatabaseGenerated", "DatabaseGeneratedOption.Identity"); } if (!property.IsPrimitive) { w.WriteAttribute(2, "NotMapped"); } string @override = property.IsDerived ? "override " : ""; w.WriteLine(2, $"public {@override}{LoadShortDataType(property.DataType)} {property.Name} {{ get; set; }}"); }
/// <summary> /// Génère l'objectcontext spécialisé pour le schéma. /// </summary> /// <remarks>Support de Linq2Sql.</remarks> /// <param name="modelRootList">Liste des modeles.</param> public void Generate(IEnumerable <ModelRoot> modelRootList) { Console.WriteLine("Generating DbContext"); var projectName = _parameters.DbContextProjectPath.Split('/').Last(); var strippedProjectName = RemoveDots(_rootNamespace); var dbContextName = $"{strippedProjectName}DbContext"; var schema = _parameters.DbSchema; if (schema != null) { dbContextName = $"{schema.First().ToString().ToUpper() + schema.Substring(1)}DbContext"; } var destDirectory = $"{_parameters.OutputDirectory}\\{_parameters.DbContextProjectPath}"; Directory.CreateDirectory(destDirectory); var targetFileName = Path.Combine(destDirectory, "generated", $"{dbContextName}.cs"); using (var w = new CSharpWriter(targetFileName)) { var usings = new List <string>(); if (_parameters.Kinetix == "Core") { usings.Add("Microsoft.EntityFrameworkCore"); } else { usings.Add("System.Data.Entity"); usings.Add("System.Transactions"); usings.Add("Kinetix.Data.SqlClient"); } foreach (ModelRoot model in modelRootList) { foreach (ModelNamespace ns in model.Namespaces.Values) { var shouldImport = ns.ClassList .Where(cl => cl.DataContract.IsPersistent) .Select(cl => cl.Namespace) .Distinct() .Any(); if (shouldImport) { usings.Add($"{_rootNamespace}.{ns.Name}"); } } } w.WriteUsings(usings.ToArray()); w.WriteLine(); w.WriteLine($"namespace {projectName}"); w.WriteLine("{"); if (_parameters.Kinetix == "Core") { w.WriteSummary(1, "DbContext généré pour Entity Framework Core."); w.WriteLine(1, $"public partial class {dbContextName} : DbContext"); w.WriteLine(1, "{"); w.WriteSummary(2, "Constructeur par défaut."); w.WriteParam("options", "Options du DbContext."); w.WriteLine(2, $"public {dbContextName}(DbContextOptions<{dbContextName}> options)"); w.WriteLine(3, ": base(options)"); w.WriteLine(2, "{"); w.WriteLine(2, "}"); } else { string inheritance = _parameters.LegacyIdentity.GetValueOrDefault() ? "" : " : DbContext"; w.WriteSummary(1, "DbContext généré pour Entity Framework 6."); w.WriteLine(1, $"public partial class {dbContextName}{inheritance}"); w.WriteLine(1, "{"); w.WriteSummary(2, "Constructeur par défaut."); w.WriteLine(2, $"public {dbContextName}()"); w.WriteLine(3, ": base(SqlServerManager.Instance.ObtainConnection(\"default\"), false)"); w.WriteLine(2, "{"); w.WriteLine(2, "}"); w.WriteLine(); w.WriteSummary(2, "Constructeur par défaut."); w.WriteParam("scope", "Transaction scope."); w.WriteLine(2, $"public {dbContextName}(TransactionScope scope)"); w.WriteLine(3, ": this()"); w.WriteLine(2, "{"); w.WriteLine(2, "}"); } foreach (ModelRoot model in modelRootList) { foreach (ModelNamespace ns in model.Namespaces.Values) { foreach (ModelClass classe in ns.ClassList.OrderBy(c => c.Name)) { if (classe.DataContract.IsPersistent) { w.WriteLine(); w.WriteSummary(2, "Accès à l'entité " + classe.Name); if (_parameters.LegacyIdentity.GetValueOrDefault() && new[] { "User", "Role" }.Contains(classe.Name)) { w.WriteLine(2, "public override IDbSet<" + classe.Name + "> " + Pluralize(classe.Name) + " { get; set; }"); } else { w.WriteLine(2, "public DbSet<" + classe.Name + "> " + Pluralize(classe.Name) + " { get; set; }"); } } } } } if (_parameters.Kinetix == "Framework") { w.WriteLine(); w.WriteSummary(2, "Hook pour l'ajout de configuration su EF (précision des champs, etc)."); w.WriteParam("modelBuilder", "L'objet de construction du modèle."); w.WriteLine(2, "protected override void OnModelCreating(DbModelBuilder modelBuilder)"); w.WriteLine(2, "{"); w.WriteLine(3, "base.OnModelCreating(modelBuilder);"); w.WriteLine(); foreach (ModelRoot model in modelRootList) { foreach (ModelNamespace ns in model.Namespaces.Values) { foreach (ModelClass classe in ns.ClassList.OrderBy(c => c.Name)) { if (classe.DataContract.IsPersistent) { foreach (ModelProperty property in classe.PropertyList) { if (property.DataType.StartsWith("decimal") && property.DataDescription.Domain.PersistentLength.HasValue && property.DataDescription.Domain.PersistentPrecision.HasValue) { w.WriteLine(3, string.Format("modelBuilder.Entity<{0}>().Property(x => x.{1}).HasPrecision({2}, {3});", classe.Name, property.Name, property.DataDescription.Domain.PersistentLength.Value, property.DataDescription.Domain.PersistentPrecision.Value )); } } } } } } w.WriteLine(); w.WriteLine(3, "OnModelCreatingCustom(modelBuilder);"); w.WriteLine(2, "}"); w.WriteLine(); w.WriteSummary(2, "Hook pour l'ajout de configuration custom sur EF (view, etc)."); w.WriteParam("modelBuilder", "L'objet de construction du modèle"); w.WriteLine(2, "partial void OnModelCreatingCustom(DbModelBuilder modelBuilder);"); } w.WriteLine(1, "}"); w.WriteLine("}"); } }