刚看了MSDN上介绍的设计模式MVP,总体感觉是它有点像MVC, 我觉得MVP主要解决的问题是UI控件重用的问题,将界面层UI涉及的业务逻辑减至最少,这样更易实现项目C/S,B/S的交换开发,因为他们共用同一的业务层。
但是这个示例有点不足的是它的业务层与控件抽象DTO层也相关,使得业务层比较复杂,业务层应该只与表示层相关联。
他原来的系统架构是这样的:

Web.UI 界面层,Presentation表示层(像业务外观层),DTO控件抽象接口层,Web.Controls控件层,Task 业务层,DataAccess数据访问层,Domain数据服务层(主要是业务数据对象)。
应该将业务层与DTO的引用断开,将DTO中的CustomerDTO对象删除,且替换为Domain的ICustomer。使得在整个应用中业务数据对象都使用Domain层的。
修改后的 MVP.Task.ICustomerTask:
public interface ICustomerTask
{
IList<ICustomer> GetCustomerList();
ICustomer GetDetailsForCustomer(int customerId);
}
修改后的 MVP.Task.CustomerTask:
public class CustomerTask : ICustomerTask
{
private readonly ICustomerMapper customerMapper;
public CustomerTask() : this(new CustomerMapper())
{
}
public CustomerTask(ICustomerMapper customerMapper)
{
this.customerMapper = customerMapper;
}
public IList<ICustomer> GetCustomerList()
{
return customerMapper.GetAllCustomers();
// new LookupCollection(new CustomerToLookupConverter().ConvertAllFrom(customerMapper.GetAllCustomers()));
}
public ICustomer GetDetailsForCustomer(int customerId)
{
ICustomer customer = customerMapper.FindById(customerId);
return customer;
}
}
将Converters文件夹下的三个转换文件移植到Presentation。
修改表示层:
namespace MVP.Presentation
{
public class ViewCustomerPresenter
{
private readonly IViewCustomerView view;
private readonly ICustomerTask task;
public ViewCustomerPresenter(IViewCustomerView view) : this(view, new CustomerTask()) {}
public ViewCustomerPresenter(IViewCustomerView view, ICustomerTask task)
{
this.view = view;
this.task = task;
}
public void Initialize()
{
this.GetLookupCollection().BindTo(view.CustomerList);
}
private ILookupCollection GetLookupCollection()
{
IList<ICustomer> oCustomers = task.GetCustomerList();
IList<ILookupDTO> oLookup = new CustomerToLookupConverter().ConvertAllFrom(oCustomers);
return new LookupCollection(oLookup);
}
public void DisplayCustomerDetails()
{
int? customerId = SelectedCustomerId;
if (customerId.HasValue)
{
ICustomer customer = task.GetDetailsForCustomer(customerId.Value);
UpdateViewFrom(customer);
}
}
private int? SelectedCustomerId
{
get
{
string selectedId = view.CustomerList.SelectedItem.Value;
if (String.IsNullOrEmpty(selectedId)) return null;
int? id = null;
try
{
id = int.Parse(selectedId.Trim());
}
catch (FormatException) {}
return id;
}
}
private void UpdateViewFrom(ICustomer customer)
{
view.CompanyName = customer.CompanyName;
view.ContactName = customer.ContactName;
view.ContactTitle = customer.ContactTitle;
view.Address = customer.Address;
view.City = customer.City;
view.Region = customer.Region;
view.Country = customer.Country.Name;
view.Phone = customer.Phone;
view.Fax = customer.Fax;
view.PostalCode = customer.PostalCode;
}
}
参考:http://www.microsoft.com/china/msdn/library/architecture/architecture/architecturetopic/MVP.mspx?mfr=true
AppDomain oDownLoadDoMain = AppDomain.CreateDomain("DownLoadDoMain", null);
利用下面的方法回报错:
oDownLoadDoMain.ExecuteAssembly("SmApp.ProgramUpdate.exe");
错误信息:“An unhandled exception of type 'System.IO.FileNotFoundException' occurred in SmApp.ProgramUpdate.UnZip.exe
Additional information: 未能加载文件或程序集“file:///E:\项目配置管理\项目管理\开发项目2006\基础地理信息系统项目插件平台\Applications\AddIn.root\AddIn\SmApp.ProgramUpdate.UnZip\bin\Debug\SmApp.ProgramUpdate.exe”或它的某一个依赖项。系统找不到指定的文件。”
后面改为调用 ExecuteAssemblyByName方法确成功了,不知是什么原因。
//注意参数必须是SmApp.ProgrameUpdate.exe的Assembly的FullName
oDownLoadDoMain.ExecuteAssemblyByName("SmApp.ProgrameUpdate, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null");
现在这房子太难找了,越来越贵;想从学知园附近找间房子太难了,普通两居就要2200多,真是吃人了。还是想等等再看吧
DevExpress 的帮助文档是在太缺乏了,他自己的帮助只有简单描述,没有样例,而它的网站上的在线帮助只有利用它的设计器设计的ToolBar、PopupMenu ,没有利用代码开发的。
虽然要利用代码开发,可以参照它设计器背后的代码,但还是有些区别的。我最近就碰见了问题:
我通过反射初始化BarButtonItem,BarSubItem按钮实例,最后在主程序把这些按钮加到ToolBar上:
在用反射实例化BarSubItem时,要用该方法:
BarSubItem newItem = new BarSubItem();
newItem.Name = intMenuItemCount.ToString();
newItem.Id = intMenuItemCount++;
newMenu.LinksPersistInfo.Add(new DevExpress.XtraBars.LinkPersistInfo((BarItem)item, beginGroup));
这里要注意:
1、Id必须唯一。
2、不要使用newMenu.AddItem((BarItem)item),这个方法会引起很多问题,如:beginGroup菜单分组无法实现, 我试图通过以下方法实现,但还是徒劳,而且有些编辑菜单不能使用该方法,如:BarToolbarsListItem工具栏列表菜单
BarItemLink itemLink = newMenu.AddItem((BarItem)item);
itemLink.BeginGroup = beginGroup;
3、在将实例化的BarSubItem加到ToolBar以后,还要递归把BarSubItem以及它的子菜单加入BarManager。
private void AddMenuItem(DevExpress.XtraBars.BarItem menuItem)
{
if (menuItem != null)
{
//如果是编辑框工具条时使用
if (menuItem is BarEditItem)
{
this.BarMenuManager.RepositoryItems.Add((menuItem as BarEditItem).Edit);
}
this.BarMenuManager.Items.Add(menuItem);
if (menuItem is DevExpress.XtraBars.BarSubItem)
{
DevExpress.XtraBars.LinksInfo linksInfo = (menuItem as DevExpress.XtraBars.BarSubItem).LinksPersistInfo;
for (int i = 0; i < linksInfo.Count; i++)
{
AddMenuItem((BarItem)linksInfo[i].Item);
}
}
}
4、如果右键菜单也是通过反射实现的,那么在加载右键菜单时需要注意:
public PopupMenu CreateContextMenu
{
PopupMenu contextMenu = new PopupMenu();
contextMenu.Popup += new EventHandler(ContextMenuPopupHandler);
foreach (object item in buildItems)
{
if (item is BarItem)
{
bool beginGroup = false;
beginGroup = (bool)(item as BarItem).Tag;
//contextMenu.LinksPersistInfo.AddRange(new LinkPersistInfo[] { new LinkPersistInfo((item as BarItem), beginGroup) });
BarItem barItem = item as BarItem;
AddMenuItem(barManager, barItem);
//用LinksPersistInfo右键菜单不出来
//contextMenu.LinksPersistInfo.Add(new LinkPersistInfo(barItem, beginGroup));
BarItemLink itemLink = contextMenu.AddItem(barItem);
itemLink.BeginGroup = beginGroup;
}
}
contextMenu.Manager = barManager;
return contextMenu;
}
//在此方法中注意 BarItemLink itemLink = (menuItem as BarSubItem).AddItem(item);此方法看似又多加了菜单,但实际不然,如果不用该方法,右键菜单中的菜单有子菜单时会无法显示。我就是让这个问题耗了我很多事间
private void AddMenuItem(DevExpress.XtraBars.BarManager barManager,DevExpress.XtraBars.BarItem menuItem)
{
if (menuItem != null)
{
barManager.Items.Add(menuItem);
if (menuItem is DevExpress.XtraBars.BarSubItem)
{
DevExpress.XtraBars.LinksInfo linksInfo = (menuItem as DevExpress.XtraBars.BarSubItem).LinksPersistInfo;
int count = linksInfo.Count;
for (int i = 0; i < count; i++)
{
BarItem item = (BarItem)linksInfo[i].Item;
item.Manager = barManager;
BarItemLink itemLink = (menuItem as BarSubItem).AddItem(item);
itemLink.BeginGroup = linksInfo[i].BeginGroup;
AddMenuItem(barManager, item);
}
}
}
}
昨天刚把数据库从SQLServer转到Oracle,今天使用时又出现了问题,插入数据没问题,问题出在更新上,更新时提示: ORA-01036: 非法的变量名/编号
关于这个提示的解答主要时以下几种:
1、Oracle的更新不能出现Parameters顺序跟传来的参数顺序不一直的问题
2、字段名太长,有的地方说是要小于32个字符,但我使用,它还要比32小,大家只能尽量控制字段名的长度(引用:
http://www.readbook8.com/dev/5201/4342318.htm)
3、虽然在Sql 语句中使用 冒号“:”代表参数,但在创建OracleParameter时,指定的参数名称不能使用冒号,在new OracleParameter时,ParameterName只能使用参数的字符部分(
http://blog.csdn.net/wwweducn/archive/2006/04/13/662054.aspx)