csharpcollegian
Member
سلام دوستان و اساتید محترم وقتتون به خیر
دوستان پیشاپیش ازتون پوزش میطلبم به خاطر اینکه این تاپیک ممکنه یه خورده طولانی بشه به این دلیل که سعی کردم کل ساختار برنامه رو با یک مثال ساده توضیح بدم و چند تا سوال بهم پیوسته رو مطرح کنم.همچنین بابت وقتی که صرف مطالعش میکنید ازتون ممنونم.
در ادامه ساختار این برنامه سه لایه رو به کمک یک مثال ساده خدمتتون توضیح میدم. فرض می کنیم که دیتابیس این برنامه از یک جدول به نام User که شامل چهار ستون به نام های ID, UserName, Date, Admin هست، تشکیل شده :
لایه UI :
در این لایه اطلاعات کاربر از فرم خونده میشه، در شی User_Value ثبت و سپس این شی یه User_BLL ازسال میشه.
لایه BLL :
در این لایه شی User_Value حاوی اطلاعات کاربره و وظیفه اعتبارسنجی این اطلاعات رو بر عهده داره.
شی User_BLL عملیات های ثبت کاربر، ویرایش کاربر و ... رو انجام میده. به این صورت که اطلاعات رو در قالب یک شی User_Value دریافت می کنه، با استفاده از کلاس MyObjectConverter اون رو تبدیل به یک دیتاتیبل می کنه و در انتها این دیتاتیبل رو برای ثبت به لایه DAL میفرسته. (البته همونطور که میدونید این شی در واقعیت شامل پیاده سازی منطق اصلی برنامه هست و این یک مثال سادست).
شی MyObjectConverter هم که وظیفه کپی اطلاعات شی در یک دیتاتیبل رو بر عهده داره.
لایه DAL :
همونطور که میبینید اطلاعات به کمک یک دیتاتیبل از لایه BLL به لایه DAL میاد و در این لایه پارامترها ساخته شده و به Stored Procedure که در بانک اطلاعاتی نوشته شده فرستاده و در بانک ثبت میشن.
نکته : لایه های DAL و BLL توسط کتابخانه کلاس پیاده سازی و به پروژه اضافه شدند. در لایه UI فقط رفرنس به لایه BLL و در لایه BLL فقط رفرنس به لایه DAL داده شده.
سوال اول :
آیا این برنامه استانداردهای معماری سه لایه رو به صورت صحیح پیاده سازی کرده ؟
سوال دوم :
همونطور که مشاهده کردید اطلاعات برنامه توسط آبجکت User از لایه UI به لایه BLL و از اونجا هم توسط یک دیتاتیبل به لایه DAL منتقل شده. خوده من به شخصه ترجیح میدم انتقال اطلاعات از لایه BLL به لایه DAL هم توسط همون آبجکت User انجام بشه (چون هم حجم کدها رو کمتر می کنه هم با توجه به تکنیک هایی که استفاده کردم کارم رو آسون تر می کنه). اما همونطور که عرض کردم لایه های DAL و BLL توسط کتابخانه کلاس تعریف شدند و اگر بخوام انتقال اطلاعات از لایه BLL به لایه DAL رو هم با استفاده از آبجکت User انجام بدم، باید در لایه DAL هم به لایه BLL رفرنس بدم(یعنی به لایه ی پایین تر دسترسی به لایه بالاتر بدم). حالا میخوام بدونم اگر این کار رو انجام بدم، باعث نقض استانداردهای معماری سه لایه در برنامم نمیشم ؟
سوال سوم :
همونطور که مشاهده می کنید من در لایه BLL با استفاده از شی MyObjectConverter اطلاعات شی User رو در یک دیتاتیبل کپی کردم. اما یک نکته در اینجا وجود داره و اونم اینه که من در زمان کپی اطلاعات، نوع داده های شی User رو در دیتاتیبل مشخص نکردم :
در صورتی که باید از کدی مشابه این استفاده می کردم :
اما از اونجاییکه بعضی از فیلدهام در آبجکت User به صورت Nullable تعریف شده اند (منطق برنامم در قسمت جستجو نیاز داره که اینطور باشن) و دیتاتیبل این رو ساپورت نمیکنه نتونستم این کار رو انجام بدم.
حالا با این شرایط که این کار رو نکردم، از چند تا متد ثبت و جستجوی ساده که تست گرفتم برنامه درست عمل کرده ! که حدس میزنم این درست عمل کردن برنامه به خاطر این باشه که در لایه DAL زمانی که فیلدهای دیتاتیبل رو به پارامترها نسبت میدادم نوع پارامتر رو مشخص کرده بودم :
که باعث شده نوع داده ها همینجا تنظیم بشه و برنامه درست عمل کنه !
میخوام بدونم آیا این حدس درسته یا کاملا اتفاقی بوده ؟
آیا این روش کاملا درسته و بعدا ممکن نیست ایجاد مشکل کنه ؟
باز هم بابت حوصله ای که به خرج دادین ازتون ممنونم
دوستان پیشاپیش ازتون پوزش میطلبم به خاطر اینکه این تاپیک ممکنه یه خورده طولانی بشه به این دلیل که سعی کردم کل ساختار برنامه رو با یک مثال ساده توضیح بدم و چند تا سوال بهم پیوسته رو مطرح کنم.همچنین بابت وقتی که صرف مطالعش میکنید ازتون ممنونم.
در ادامه ساختار این برنامه سه لایه رو به کمک یک مثال ساده خدمتتون توضیح میدم. فرض می کنیم که دیتابیس این برنامه از یک جدول به نام User که شامل چهار ستون به نام های ID, UserName, Date, Admin هست، تشکیل شده :
لایه UI :
PHP:
private void button1_Click(object sender, EventArgs e)
{
if (txtID.Text != "" && txtUserName.Text != "")
{
BusinessLogicLib.User_Value userValueObj = new User_Value();
userValueObj.ID = (int)txtID.Text;
userValueObj.UserName = txtUserName.Text;
userValueObj.Date = DateTime.Now;
userValueObj.Admin = chbxAdmin.Checked;
BusinessLogicLib.User_BLL userBllObj = new User_BLL();
userBllObj.CreateUser(userValueObj);
}
}
لایه BLL :
PHP:
class User_Value
{
private int? id;
private string userName;
private DateTime? date;
private bool? admin;
.
. //Properties
.
}
PHP:
class User_BLL
{
DataAccessLib.User_DAL userDalObj = new DAL.User_DAL();
public void CreateUser(User_Value userValueObj)
{
DataTable dtUser = MyObjectConverter.ConvertToDataTable(userValueObj);
userDalObj.Insert(dtUser);
}
.
. //Other Methods
.
}
PHP:
class MyObjectConverter
{
public static DataTable ConvertToDataTable(Object Obj)
{
PropertyInfo[] fields = Obj.GetType().GetProperties();
DataTable dt = new DataTable();
DataColumn column;
foreach (PropertyInfo Property in Properties)
{
column = new DataColumn();
column.ColumnName = Property.Name;
dt.Columns.Add(column);
}
DataRow row = dt.NewRow();
foreach (PropertyInfo Property in Properties)
{
row[Property.Name] = Property.GetValue(Obj);
}
dt.Rows.Add(row);
return dt;
}
}
شی User_BLL عملیات های ثبت کاربر، ویرایش کاربر و ... رو انجام میده. به این صورت که اطلاعات رو در قالب یک شی User_Value دریافت می کنه، با استفاده از کلاس MyObjectConverter اون رو تبدیل به یک دیتاتیبل می کنه و در انتها این دیتاتیبل رو برای ثبت به لایه DAL میفرسته. (البته همونطور که میدونید این شی در واقعیت شامل پیاده سازی منطق اصلی برنامه هست و این یک مثال سادست).
شی MyObjectConverter هم که وظیفه کپی اطلاعات شی در یک دیتاتیبل رو بر عهده داره.
لایه DAL :
PHP:
public class User_DAL
{
public void Insert(DataTable dtUser)
{
SqlParameter idParam = new SqlParameter("@ID", SqlDbType.Int);
idParam.Value = dtUser.Rows[0]["ID"];
SqlParameter usernameParam = new SqlParameter("@UserName", SqlDbType.NVarChar);
usernameParam.Value = dtUser.Rows[0]["UserName"];
SqlParameter dateParam = new SqlParameter("@StartDate", SqlDbType.Date);
dateParam.Value = dtUser.Rows[0]["Date"];
SqlParameter adminParam = new SqlParameter("@Admin", SqlDbType.Bit);
adminParam.Value = dtUser.Rows[0]["Admin"];
.
. //Inserting Parameters Into DataBase By StoredProcedure
.
}
.
. //Other Methods
.
}
نکته : لایه های DAL و BLL توسط کتابخانه کلاس پیاده سازی و به پروژه اضافه شدند. در لایه UI فقط رفرنس به لایه BLL و در لایه BLL فقط رفرنس به لایه DAL داده شده.
سوال اول :
آیا این برنامه استانداردهای معماری سه لایه رو به صورت صحیح پیاده سازی کرده ؟
سوال دوم :
همونطور که مشاهده کردید اطلاعات برنامه توسط آبجکت User از لایه UI به لایه BLL و از اونجا هم توسط یک دیتاتیبل به لایه DAL منتقل شده. خوده من به شخصه ترجیح میدم انتقال اطلاعات از لایه BLL به لایه DAL هم توسط همون آبجکت User انجام بشه (چون هم حجم کدها رو کمتر می کنه هم با توجه به تکنیک هایی که استفاده کردم کارم رو آسون تر می کنه). اما همونطور که عرض کردم لایه های DAL و BLL توسط کتابخانه کلاس تعریف شدند و اگر بخوام انتقال اطلاعات از لایه BLL به لایه DAL رو هم با استفاده از آبجکت User انجام بدم، باید در لایه DAL هم به لایه BLL رفرنس بدم(یعنی به لایه ی پایین تر دسترسی به لایه بالاتر بدم). حالا میخوام بدونم اگر این کار رو انجام بدم، باعث نقض استانداردهای معماری سه لایه در برنامم نمیشم ؟
سوال سوم :
همونطور که مشاهده می کنید من در لایه BLL با استفاده از شی MyObjectConverter اطلاعات شی User رو در یک دیتاتیبل کپی کردم. اما یک نکته در اینجا وجود داره و اونم اینه که من در زمان کپی اطلاعات، نوع داده های شی User رو در دیتاتیبل مشخص نکردم :
PHP:
class MyObjectConverter
{
public static DataTable ConvertToDataTable(Object Obj)
{
.
.
.
foreach (PropertyInfo Property in Properties)
{
**********************
column = new DataColumn();
column.ColumnName = Property.Name;
dt.Columns.Add(column);
**********************
}
.
.
.
}
}
PHP:
class MyObjectConverter
{
public static DataTable ConvertToDataTable(Object Obj)
{
.
.
.
foreach (PropertyInfo Property in Properties)
{
**********************
column = new DataColumn();
column.ColumnName = Property.Name;
column.DataType = Property.PropertyType;
dt.Columns.Add(column);
**********************
}
.
.
.
}
}
حالا با این شرایط که این کار رو نکردم، از چند تا متد ثبت و جستجوی ساده که تست گرفتم برنامه درست عمل کرده ! که حدس میزنم این درست عمل کردن برنامه به خاطر این باشه که در لایه DAL زمانی که فیلدهای دیتاتیبل رو به پارامترها نسبت میدادم نوع پارامتر رو مشخص کرده بودم :
PHP:
public class User_DAL
{
public void Insert(DataTable dtUser)
{
SqlParameter idParam = new SqlParameter("@ID", ****SqlDbType.Int****);
idParam.Value = dtUser.Rows[0]["ID"];
SqlParameter usernameParam = new SqlParameter("@UserName", ****SqlDbType.NVarChar****);
usernameParam.Value = dtUser.Rows[0]["UserName"];
.
.
.
}
میخوام بدونم آیا این حدس درسته یا کاملا اتفاقی بوده ؟
آیا این روش کاملا درسته و بعدا ممکن نیست ایجاد مشکل کنه ؟
باز هم بابت حوصله ای که به خرج دادین ازتون ممنونم