2009-06-11 9 views
3

私は、Subsonicを使って素晴らしいDALを生成しました。 BLLのスケルトンを生成する方法はありますか?私はSS層を私のGUIに直接接続したくない。亜音速:仲間の層

私は両方のSSフォーラムを通じてtrudgedたのだが、誰も通話 SSS-生成層DALようだが、彼らはBLLとしてにそれを使う

BLLを手作業でコーディングすることなく、SSを使用してDALおよびBLL層を分離しましたか?

+2

+1質問タイトルについて – womp

+0

+1同上。私は嫉妬深いです。 –

答えて

1

いいえ、ただし、いくつかのオプションがあります。生成されたテーブルクラスを部分クラスファイルで拡張して、より多くのロジックを追加することができます。これは、多くの小規模なアプリケーションにとって十分です。また、DTOクラスも必要な場合があります。また、サブソニック3のテーブルクラスは、通常、DTOオブジェクトとして機能するようです。サブソニック3で追加のt4テンプレートファイルを作成して、テーブルごとに1つのクラスのビジネスクラスを作成することができます。コードは既存のテンプレートコードとよく似ていますので、かなり簡単になります。 ss3のテーブルクラスのテンプレートコードを取得し、ss2でそれらを使用してファイルを生成することもできます。これは、BLLクラスの単純なセットをどれくらい生成したいかによって異なります。

+0

ありがとうございます。私はSSに別のテンプレートを生成させようとします。 –

1

はい私は、プロジェクトが本当に小さく、ビジネスロジックがあまりない場合を除いて、別々のDALとBLLを使用します。

DALプロパティが本当に面倒でSSのコード生成の良さを打ち破っているため、BALのすべての実装を正しく実行しています。私は、DALを通り、スケルトンBLLを分解する小さなコンソールアプリケーションを作成しました:

ここにそのコードがあります。それは非常に、粗1(私はそれがSO仲間で精査し、それを改善し得ることを期待して、ここでそれを貼り付けています)であることを忘れないでください:

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: - 場合YOUR_DAL_NAMESPACE、YOUR_BLL_NAMESPACEとYOUR_NAMEプレースホルダの世話をしてくださいあなたはそれを試してみましょう。