2009-06-11 6 views
3

J'ai une belle couche DAL générée en utilisant Subsonic. Y a-t-il un moyen de générer un squelette pour la BLL? Je ne veux pas brancher la couche SS directement dans mon interface graphique.Subsonic: Niveaux d'un clown

J'ai trudged dans les forums SS et il semble que tout le monde appelle la couche générée par SSS une DAL, mais ils utilisent comme un BLL.

Avez-vous utilisé SS et séparé les niveaux DAL et BLL sans coder manuellement le BLL à partir de zéro?

+2

+1 pour le titre de la question – womp

+0

+1 ditto. Je suis tellement jaloux. –

Répondre

1

Non, mais il existe certaines options. Vous pouvez étendre les classes de tables générées avec des fichiers de classe partiels pour ajouter plus de logique, ce qui peut être suffisant pour de nombreuses applications plus petites. Vous pouvez également avoir besoin de classes DTO, et les classes de tables de subsonic 3 semblent généralement fonctionner comme des objets DTO. Vous pouvez écrire des fichiers de modèle t4 supplémentaires dans subsonic 3 pour créer des classes métier, une classe par table. Le code ressemblera beaucoup au code existant, il devrait donc être assez facile. Vous pouvez même prendre le code du template pour les classes de table dans ss3 et les utiliser dans ss2 pour générer des fichiers. Cela dépend de la façon dont vous voulez générer un simple ensemble de classes BLL.

+0

Merci les gars. Je vais essayer d'obtenir SS pour générer un autre modèle. –

1

Oui, j'utilise DAL et BLL séparés sauf lorsque le projet est vraiment petit et qu'il n'y a pas beaucoup de logique métier.

Vous avez raison de faire toute la mise en œuvre dans BAL pour les propriétés DAL est vraiment fastidieux et bat la qualité de génération de code de SS. J'ai créé une petite application de console qui passe par DAL et produit des BLL de squelette:

Voici le code de celui-ci. S'il vous plaît rappelez-vous qu'il est très brut (je le coller ici dans l'espoir de l'obtenir scruté par SO boursiers et de l'améliorer):

class Program 
{ 
    static void Main(string[] args) 
    { 
     InitTypesDictionary(); 
     ProcessFile("c:\\temp\\myBll", "YOUR_BLL_NAMESPACE");//args[0], args[1]); 

     Console.ReadLine(); 
    } 

    private static void InitTypesDictionary() 
    { 
     typesMap = new Dictionary<string, string>(); 
     typesMap.Add("System.String", "string"); 
     typesMap.Add("System.Int32", "int"); 
     typesMap.Add("System.Decimal", "decimal"); 
     typesMap.Add("System.Double", "double"); 
     typesMap.Add("System.Guid", "Guid"); 
     typesMap.Add("System.DateTime", "DateTime"); 
     typesMap.Add("System.Boolean", "bool"); 
     typesMap.Add("System.Byte", "byte"); 
     typesMap.Add("System.Short", "short"); 
     typesMap.Add("System.Nullable`1[System.Int32]", "int?"); 
     typesMap.Add("System.Nullable`1[System.DateTime]", "DateTime?"); 
     typesMap.Add("System.Nullable`1[System.Decimal]", "decimal?"); 
     typesMap.Add("System.Nullable`1[System.Double]", "double?"); 
     typesMap.Add("System.Nullable`1[System.Boolean]", "bool?"); 
    } 

    private static void WriteError(string msg) 
    { 
     WriteInfo(msg, ConsoleColor.Red); 
    } 

    private static void WriteTypeName(string name) 
    { 
     WriteInfo(name, ConsoleColor.Blue); 
    } 

    private static void WriteInfo(string info, ConsoleColor cc) 
    { 
     ConsoleColor clr = Console.ForegroundColor; 
     Console.ForegroundColor = cc; 
     Console.WriteLine(info); 
     Console.ForegroundColor = clr; 
    } 

    private static void ProcessFile(string savePath, string _namespace) 
    { 
     Assembly asm = Assembly.GetAssembly(typeof(ROMS.DAL.RomsAdBusiness)); 
     //Assembly asm = Assembly.ReflectionOnlyLoad("ROMS.DAL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"); 

     Type[] types = asm.GetTypes(); 

     foreach (Type t in types) 
     { 
      if (t.BaseType.Name.Contains("ActiveRecord")) 
      { 
       WriteTypeName("Processing " + t.Name); 
       ProcessType(t, savePath, _namespace); 
      } 
     } 
    } 

    private static void ProcessType(Type t, string path, string nsp) 
    { 
     string className = t.Name.Substring(4); 

     StringBuilder sbCode = new StringBuilder(); 

     sbCode.Append(imports); 
     //sbCode.Append(Environment.NewLine); 

     sbCode.AppendFormat(comments, t.Name, DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss")); 

     sbCode.AppendFormat(namespaceStart, nsp); 
     //sbCode.Append(Environment.NewLine); 

     sbCode.AppendFormat(_class, className); 
     //sbCode.Append(Environment.NewLine); 

     sbCode.AppendFormat(dalObject, t.Name); 

     sbCode.AppendFormat(regionStart, "ctor"); 
     //sbCode.Append(Environment.NewLine); 

     sbCode.AppendFormat(ctorString, className, t.Name); 

     sbCode.AppendFormat(ctorStringPK, className, t.Name); 

     sbCode.AppendFormat(ctorStringObject, className, t.Name); 

     sbCode.AppendFormat(regionEnd, ""); 
     //sbCode.Append(Environment.NewLine); 

     PropertyInfo[] properties = t.GetProperties(); 

     //if (properties.Count() > 0) 
     //{ 
     sbCode.AppendFormat(regionStart, "Properties"); 
     //sbCode.Append(Environment.NewLine); 
     //} 

     foreach (PropertyInfo p in properties) 
     { 
      if (SkipProperties.Contains(p.Name)) continue; 

      if (p.Name == className) 
       sbCode.AppendFormat(propertyValue, GetPropertyTypeName(p.PropertyType.ToString()), p.Name + "Value", p.Name); 
      else if (p.Name.ToLower().Contains("roms")) 
       sbCode.AppendFormat(propertyInternal, GetPropertyTypeName(p.PropertyType.ToString()), p.Name); 
      else 
       sbCode.AppendFormat(property, GetPropertyTypeName(p.PropertyType.ToString()), p.Name); 

      //sbCode.Append(Environment.NewLine); 
     } 

     sbCode.Append(isNew_Validate_Properties); 


     //if (properties.Count() > 0) 
     //{ 
     sbCode.AppendFormat(regionEnd, ""); 
     //sbCode.Append(Environment.NewLine); 
     //} 

     sbCode.AppendFormat(regionStart, "methods"); 
     sbCode.Append(saveMethod); 
     sbCode.Append(deleteMethod.Replace("_CLASSNAME_", className)); 
     sbCode.AppendFormat(regionEnd, ""); 

     //Add Fetch as Collection Methods 
     sbCode.Append(getCollectionsMethods.Replace("_CLASSNAME_", className).Replace("_DOUBLEQUOTE_", "\"")); 

     //Define Columns Structure 
     Type cols = t.GetNestedType("Columns"); 
     if (cols != null) 
     { 
      StringBuilder sbCols = new StringBuilder(columnsStructStart); 
      MemberInfo[] fields = cols.GetMembers(); 
      foreach (MemberInfo mi in fields) 
      { 
       if (mi.MemberType == MemberTypes.Field) 
        sbCols.AppendFormat(columnDeclaration, mi.Name); 
      } 
      sbCols.Append(columnsStructEnd); 
      sbCode.Append(sbCols.ToString()); 
     } 

     sbCode.Append("}_NL_}_NL_"); 
     var fileName = WriteFile(path, nsp, className, sbCode); 
     WriteInfo("Written file: " + fileName, ConsoleColor.Yellow); 
    } 

    private static string GetPropertyTypeName(string s) 
    { 
     if (typesMap.ContainsKey(s)) return typesMap[s]; 

     if (s.Contains("Nullable`")) 
     { 
      s = s.Substring(s.IndexOf("[") + 1); 
      s = s.Substring(0, s.IndexOf("]")); 

      if (typesMap.ContainsKey(s)) 
       return typesMap[s] + "?"; 
      else 
       return "Nullable<" + s + ">"; 
     } 

     if (s.StartsWith("System.")) 
      return s.Substring(7); 

     if (s.LastIndexOf(".") > 0) 
      return s.Substring(s.LastIndexOf(".") + 1); 

     return s; 
    } 

    private static string WriteFile(string path, string nsp, string typeName, StringBuilder sbCode) 
    { 
     string filename = GetFilePath(path, nsp, typeName); 
     TextWriter tw = new StreamWriter(filename); 
     StringBuilder sb = sbCode.Replace("_BS_", "{") 
      .Replace("_BE_", "}") 
      .Replace("_NL_", Environment.NewLine) 
      .Replace("_DOUBLEQUOTE_", "\""); 
     tw.Write(sb.ToString()); 
     tw.Flush(); 
     tw.Close(); 
     return filename; 
    } 

    private static string GetFilePath(string path, string nsp, string typeName) 
    { 
     path = path.EndsWith("\\") ? path : path + "\\"; 
     path += typeName + ".cs"; 
     return path; 
    } 

    static bool IsNullableType(Type theType) 
    { 
     return (theType.IsGenericType && theType. 
      GetGenericTypeDefinition().Equals 
      (typeof(Nullable<>))); 
    } 

    private static string[] SkipProperties = new[]{"IsLoaded", "IsNew", "IsDirty", 
     "TableName", "ProviderName",   
    "NullExceptionMessage","InvalidTypeExceptionMessage", 
     "LengthExceptionMessage",   
    "AuditId","Schema","ValidateWhenSaving","DirtyColumns","Errors"}; 

    static IDictionary<string, string> typesMap; 

    static string comments = @"_NL_///<sumary> 
    ///This class uses {0} from YOUR_DAL_NAMESPACE 
    ///Created by MyCodeGen (YOUR_NAME) on {1} 
    ///</sumary>_NL_"; 
    static string dalObject = "_NL_private YOUR_DAL_NAMESPACE.{0} _dalObject;_NL_"; 
    static string namespaceStart = "namespace {0} _NL_ _BS_ _NL_"; 
    static string property = "public {0} {1} _NL_ _BS_ _NL_ get _BS_ return   
    _dalObject.{1}; _BE_ _NL_ " + 
     "set _BS_ _dalObject.{1} = value; _BE_ _NL_ _BE_ _NL_"; 
    static string propertyInternal = "internal {0} {1} _NL_ _BS_ _NL_ get _BS_ return 
    _dalObject.{1}; _BE_ _NL_ " + 
     "set _BS_ _dalObject.{1} = value; _BE_ _NL_ _BE_ _NL_"; 
    static string propertyValue = "public {0} {1} _NL_ _BS_ _NL_ get _BS_ return 
    _dalObject.{2}; _BE_ _NL_ " + 
       "set _BS_ _dalObject.{2} = value; _BE_ _NL_ _BE_ _NL_"; 
    static string _class = "public partial class {0} _NL_ _BS_ "; 
    static string regionStart = "#region {0} _NL_"; 
    static string regionEnd = "#endregion{0}_NL__NL_"; 
    static string ctorString = "[DebuggerStepThrough]_NL_public {0}() _NL_ 
    _BS__NL__dalObject = new YOUR_DAL_NAMESPACE.{1}(); _NL_ _BE_ _NL_"; 
    static string ctorStringPK = "[DebuggerStepThrough]_NL_public {0}(int pk) _NL_ 
    _BS__NL__dalObject = new YOUR_DAL_NAMESPACE.{1}(pk);_NL__BE__NL_"; 
    static string ctorStringObject = "[DebuggerStepThrough]_NL_public 
    {0}(YOUR_DAL_NAMESPACE.{1} dalObject) _NL_ _BS__NL__dalObject = dalObject; _NL_ 
    if(_dalObject==null) _NL__dalObject = new YOUR_DAL_NAMESPACE.{1}();_BE_ _NL_"; 

    static string columnsStructStart = @"_NL_#region Columns Struct 
    public struct Columns 
    { 
    "; 
    static string [email protected]" 
} 
#endregion_NL_"; 
    static string columnDeclaration = "public static string   
    {0}=_DOUBLEQUOTE_{0}_DOUBLEQUOTE_;_NL_"; 
    static string saveMethod = "_NL_public bool Save() _NL__BS__NL_bool ret=IsValid;   
    _NL_ if(ret)_NL__dalObject.Save(); _NL_ return ret;_NL__BE__NL_"; 

    static string deleteMethod = @"public int Delete() 
    { 
     string pkColumn=_dalObject.GetSchema().PrimaryKey.ColumnName; 
     object pkValue = _dalObject.GetColumnValue(pkColumn); 

     return ActiveRecord<Roms_CLASSNAME_>.Delete(pkValue); 
    } 
    "; 

    static string isNew_Validate_Properties = @"/// <summary> 
    /// Enquiries underlying database object to know if it is persisted in 
    ///database or not. 
    /// True if object has never been saved to database, false otherwise 
    /// </summary> 
    public bool IsNew 
    _BS_ 
     get _BS_ return _dalObject.IsNew; _BE_ 
    _BE_ 

    /// <summary> 
    /// Validates the underlying dataobject for the lengeth, range of the 
    ///columns defined 
    /// in database. Should be called before pushing object to database 
    ///(before saving or updating). 
    /// </summary> 
    public bool IsValid 
    _BS_ 
     get _BS_ return _dalObject.Validate(); _BE_ 
    _BE_ 

    /// <summary> 
    /// This string of validation error messages (&lt;br/&gt; seperated) 
    /// if the object is not valid. 
    /// </summary> 
    /// <returns>string</returns> 
    public string GetErrors 
    _BS_ 
     get 
     _BS_ 
      StringBuilder sb=new StringBuilder(); 
      foreach (var v in _dalObject.GetErrors()) 
       sb.AppendFormat(_DOUBLEQUOTE__BS_0_BE_<br/>_DOUBLEQUOTE_, v); 
      return sb.ToString(); 
     _BE_ 
    _BE__NL_"; 

    static string imports = 
    @"using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Text; 
    using System.Data; 
    using System.Diagnostics; 
    using System.Reflection; 
    using SubSonic; 
    using YOUR_DAL_NAMESPACE; 
    "; 

    static string getCollectionsMethods = @"#region Fetch as Collection Methods 
    ///<sumary> 
    ///Returns the collection containing objects of type _CLASSNAME_ corresponding to   
    _CLASSNAME_Collection 
    ///objects passed 
    ///</sumary> 
    [DebuggerStepThrough] 
    public static IList<_CLASSNAME_> _CLASSNAME_s(Roms_CLASSNAME_Collection coll) 
    { 
     IList<_CLASSNAME_> list=new List<_CLASSNAME_>(); 

     foreach(var roprof in coll) 
      list.Add(new _CLASSNAME_(roprof)); 

     return list; 
    }   

    /// <summary> 
    /// Returns the IList&lt;_CLASSNAME_&gt; of _CLASSNAME_ objects 
    /// </summary> 
    /// <returns>IList&lt;_CLASSNAME_&gt;</returns> 
    [DebuggerStepThrough] 
    public static IList<_CLASSNAME_> _CLASSNAME_s() 
    { 
     return _CLASSNAME_s(_DOUBLEQUOTE__DOUBLEQUOTE_,null); 
    } 

    /// <summary> 
    /// Returns the IList&lt;_CLASSNAME_&gt; of _CLASSNAME_ objects having 
    /// value of <see cref=_DOUBLEQUOTE_columnName_DOUBLEQUOTE_/> = 
    ///<see cref=_DOUBLEQUOTE_value_DOUBLEQUOTE_/> 
    /// </summary> 
    /// <param name=_DOUBLEQUOTE_columnName_DOUBLEQUOTE_>Name of the column</param> 
    /// <param name=_DOUBLEQUOTE_value_DOUBLEQUOTE_>Value of the column</param> 
    /// <returns>IList&lt;_CLASSNAME_&gt;</returns> 
    [DebuggerStepThrough] 
    public static IList<_CLASSNAME_> _CLASSNAME_s(string columnName, object value) 
    { 
     IList<_CLASSNAME_> collection = new List<_CLASSNAME_>(); 

     Roms_CLASSNAME_Collection coll = null; 

     if (!string.IsNullOrEmpty(columnName)) 
     { 
      Roms_CLASSNAME_ obj = new Roms_CLASSNAME_(); 

      columnName = obj.GetType().GetNestedType(
        _DOUBLEQUOTE_Columns_DOUBLEQUOTE_). 
      GetField(columnName).GetValue(obj).ToString(); 
     } 

     if (!string.IsNullOrEmpty(columnName) && value != null) 
     { 
      coll = (new Roms_CLASSNAME_Collection()).Where(columnName, 
        value).Load(); 
     } 
     else 
     { 
      coll = (new Roms_CLASSNAME_Collection()).Load(); 
     }   

     if (coll != null) 
      foreach (var v in coll) 
       collection.Add(new _CLASSNAME_(v)); 

     return collection; 
    } 
#endregion 
"; 

PS: - S'il vous plaît prendre soin d'espaces réservés YOUR_DAL_NAMESPACE, YOUR_BLL_NAMESPACE et si votre_nom jamais vous l'essayez.