petshop4.0学习笔记(一)
petshop4.0源代码有十几二十个解决方案,代码之间的关系又是很复杂(对我等菜鸟而言),所以决定从网站首页中间的目录列表开始顺藤摸瓜,往下看。
首页那个目录列表是一个用户控件,控件地址是/web/Controls/NavigationControl.ascx。
ascx页里面用的是一个repeater控件,在里面是一个表格,表格的内容是一个HyperLink控件,HyperLink控件的显示名称和实际链接地址里绑定了数据。
ascx.cs页里,BindCategories() 函数是关键
private void BindCategories() {
Category category = new Category();
repCategories.DataSource = category.GetCategories();
repCategories.DataBind();
}
这里是设置前台页面的repeater控件的数据源。通过Category类的GetCategories返回数据集合。
Category类在/BLL/Category.cs里面定义

public class Category {
private static readonly ICategory dal = PetShop.DALFactory.DataAccess.CreateCategory();
public IList<CategoryInfo> GetCategories() {
return dal.GetCategories();
}
}
由此看来,Category类的GetCategories方法实际是通过dal.GetCategories()实现的。
ICategory是一个接口,在/IDAL/ICategory.cs里面定义的
public interface ICategory {
IList<CategoryInfo> GetCategories();
}
接口里定义了一个GetCategories方法,但是这个方法现在只有定义,还没有实现,所以接口dal的GetCategories方法与PetShop.DALFactory.DataAccess.CreateCategory()这个东西有关系。
(这里面有个让我迷糊的东西IList<CategoryInfo>,这个东西像是接口,又像泛型,据说是泛型接口,可为什么当成数据类型返回呢,现在还不太明白,我只是把它当做是一个CategoryInfo类的集合)
PetShop.DALFactory.DataAccess.CreateCategory()明显是在/DALFactory/DataAccess.cs里面定义的。

public sealed class DataAccess {
private static readonly string path = ConfigurationManager.AppSettings["WebDAL"];
public static PetShop.IDAL.ICategory CreateCategory() {
string className = path + ".Category";
return (PetShop.IDAL.ICategory)Assembly.Load(path).CreateInstance(className);
}
}
这里面关键是Assembly.Load(path).CreateInstance(className)这个函数,这里的意思是创建一个path程序集里面的className这个类的对象。回头想想,也就是说接口dal的GetCategories方法的实现将会在path程序集里面的className类里面实现。
path程序集里面的className类也就是在/SQLServerDAL/Category.cs里面定义的。

public class Category : ICategory {
private const string SQL_SELECT_CATEGORIES = "SELECT CategoryId, Name, Descn FROM Category";
public IList<CategoryInfo> GetCategories() {
IList<CategoryInfo> categories = new List<CategoryInfo>();
using(SqlDataReader rdr = SqlHelper.ExecuteReader(SqlHelper.ConnectionStringLocalTransaction,
CommandType.Text, SQL_SELECT_CATEGORIES, null)) {
while (rdr.Read()) {
CategoryInfo cat = new CategoryInfo(rdr.GetString(0), rdr.GetString(1), rdr.GetString(2));
categories.Add(cat);
}
}
return categories;
}
}
好了,到了这里已经看到熟悉的SQL语句了,说明已经到了底层了,还有一个SqlHelper类也是数据访问层的,放的一些公用的数据访问的代码。
现在思路已经基本清晰了,其它的继续研究......
(ps:接口不就是c++里面的虚基类吗?泛型不就是c++里面的模板吗?)