最近做了一个软件,这个软件不是网站,但是与HTML,AJAX等技术密切相关,也不是只有单纯的数据库增删改查,还涉及到线程协调,比较复杂的文本处理……

这样的软件,用OA,ERP的框架显然是不合适的,因为这种软件用不上权限管理,工作流这些技术。但是软件又要操作数据库。

介于这些的特殊性,想来想去,还是自己搭建一个轻量级的软件框架是比较好的。

一:C/S与B/S的选择

1,我做的是一个购物网站的刷单软件,有如下几个方面的原因,我选择了C/S程序

a,刷单软件需要长时间的运行,不定时,不间断的去访问购物网站。

b,有时候有多个线程的需要。

c,程序运行时,需要操作本地文件的权限,要把关键页面截图(如添加收藏,货比三家)保存到本地,然后上传到服务器。

d,C#的Httpresponse,HttpRequest对象运行在不同的电脑上,有不同的外网IP,如果做成网站,Httpresponse,HttpRequest永远只是在服务器上运行,外网IP只有一个。

2,在桌面运用程序方面,我感觉用WPF要比用WinForm好。

a,WPF的UI做出的产品肯定要比WinForm专业,这一点是谁都不能否认的。

b,WPF技术运用了XAML语法,这个比WinForm好用。

c,WPF可以用到MVVM模式,这点WinForm是永远都做不到的,并且MVVM有比较成熟的产品(MVVMLight, Caliburn.Micro,Prism)等产品

在这儿选用的是Caliburn.Micro框架,优点在于有命名的自动匹配,发布/订阅的消息模式,IOC的解耦,我举两个例子说明一下吧:

例一,IOC创建对象

我的项目 Trade.WPFClient  要用到  Trade.WPFBusinessPart 的页面,正常情况下 Trade.WPFClient  要添加项目 Trade.WPFBusinessPart的引用。

但是用Caliburn.Micro是不用添加引用的。

只添要在引导程序中AppBootstrapper.cs中的配置加添加如下代码:

protected override void Configure()
{
foreach (var file in System.IO.Directory.GetFiles(System.IO.Directory.GetCurrentDirectory(), "Trade.*.dll"))
{
AssemblySource.Instance.Add(Assembly.LoadFile(file));
} var catalog =
new AggregateCatalog(
AssemblySource.Instance.Select(x => new AssemblyCatalog(x)).OfType<ComposablePartCatalog>()); this.container = new CompositionContainer(catalog); var batch = new CompositionBatch(); batch.AddExportedValue<IWindowManager>(new WindowManager());
batch.AddExportedValue<IEventAggregator>(new EventAggregator());
batch.AddExportedValue(this.container);
batch.AddExportedValue(catalog); this.container.Compose(batch);
}

在使用的时候,用IOC的方式创建对象:

UserCenterViewModel userCenter = (UserCenterViewModel)IoC.Get<IUserCenter>();
bool? userCenterVal = IoC.Get<IWindowManager>().ShowDialog(userCenter);

根本就不用引用一个类库,然后new一个对象。做到了高内聚,低耦合的原则。

例二:发布/订阅模式编

先要定义一个接口,我的项目是以 Trade.BaseInterface  这个类库作为我的接口库类。

在发布页面:

方法一是同步UI发布事件,

方法二是新开一个Task来发布一个事件。也就是异步发布事件。

然后在另外一个页面接收这个发布的事件:

这样就实现了两个类库之间互相不添加引用的情况下,把消息通知给另外一个类库。

二:数据库的持久化操作

数据库持久化操作经历了很多阶段,

1,SqlHelper阶段

2,enterprise library阶段

3,Ibatis,Dapper阶段

4,Linq, Nhibernate, EntityFramework阶段。

这几种操作,我在实战项目中都使用过,犹其是EntityFramework,不管是Code Frist 模式,Mode First模式,还是Data First模式,好几年前就用在项目中做过比较了。

但是我最认可的还是Dapper。

来一段码:

/// <summary>
/// 根据用户ID获取用户的相关信息
/// </summary>
/// <param name="dContext"></param>
/// <param name="userID"></param>
/// <returns></returns>
public TradeUserModel GetTradeUserByUserID(DataContextBase dContext, String userID)
{
TradeUserModel result = default(TradeUserModel);
String querySql = @"select * from TradeUser where UserID = @UserID;
select ROW_NUMBER() over (order by DoBindingDTime desc) as RowNo, * from Member where IsDelete = '0' and UserID = @UserID;
select * from Member where IsDelete = '0' and IsCurrent = '1' and UserID = @UserID ";
var multi = dContext.Connection.QueryMultiple(querySql, new { UserID = userID }, dContext.Transaction);
result = multi.Read<TradeUserModel>().FirstOrDefault();
List<MemberModel> memberList = multi.Read<MemberModel>().ToList();
MemberModel currentMember = multi.Read<MemberModel>().FirstOrDefault();
result.MemberList = new ObservableCollection<MemberModel>(memberList);
MoneyRepository moneyRepository = new MoneyRepository();
decimal totalMoneyIn = moneyRepository.GetBusinessMoneyByUserID(dContext, userID, "In", new string[] { "RechargeMoney", "" });
decimal totalMoneyOut = moneyRepository.GetBusinessMoneyByUserID(dContext, userID, "Out", new string[] { "TakeMoney", "TaskOut", });
decimal totalTransferMoneyIn = moneyRepository.GetBusinessMoneyByUserID(dContext, userID, "In", new string[] { "TransferMoneyIn", "" });
decimal totalTransferMoneyOut = moneyRepository.GetBusinessMoneyByUserID(dContext, userID, "Out", new string[] { "TransferMoneyOut", "" });
result.TotalEnableMoney = totalMoneyIn + totalMoneyOut;
result.TotalNotEnableMoney = ;
result.TotalTransferMoney = totalTransferMoneyIn + totalTransferMoneyOut;
result.CurrentMember = currentMember; // currentMember ?? new MemberModel();
return result;
}

我一段Sql执行了三个查询,用QueryMultiple取得不同的查询结果,最神奇的地方,是查询出来的字段,不用手动赋值,Dapper可以自动实现。比如

public List<InvitationModel> GetInvitationCollectionByOwner(DataContextBase dContext, InvitationModel invitationData)
{
List<InvitationModel> result = default(List<InvitationModel>);
String querySql = @"select ROW_NUMBER() over (order by CreateDTime desc) as RowNo
, tu1.UserName as OwnerInfoName, tu2.UserName as ComputerUniqueName, i.* from Invitation i
left join TradeUser tu1 on i.OwnerInfo = tu1.UserID
left join TradeUser tu2 on i.ComputerUnique = tu2.UserID
where OwnerInfo = @OwnerInfo;";
result = dContext.Connection.Query<InvitationModel>(querySql, invitationData, dContext.Transaction).ToList();
return result;
}

这样的我查询结果就直接 赋值给 InvitationModel 类了。

三:项目中实体对象的共用

理论上,应该要申明一个类与表的字段对应

如果是用WCF作为通信传输,还得声明一个DataContract 数据契约类

如果是用的MVVM框,还得要有一个ViewModel类

三个类这间,要转换赋值,有类似 automapper 这样的工具,但是我还是不建议转换去,转换来的。

我直接把这个三个不同地方的类给共用起来。

比如我的实体类如下:

[DataContract]
public class LogModel : NotifyPropertyChanged
{
private Guid _logID;
[DataMember]
public Guid LogID
{
get
{
return _logID;
}
set
{
_logID = value;
OnPropertyChanged("LogID");
}
} ……

1,可以运作WCF的数据契约传输,

2,还可以作为MVVM的ViewModel

3,还可以与数据库字段在ORM时相互映射

一箭三雕啊

结语:

这个项目还运用到了很多技术,如如线程的管理,解析网页(网页异步加载情下)是怎么处理的?

等下一篇博客再说。

如果对这个软件感觉兴趣的,可看上一篇博客。谢谢!

WPF +MVVM(Caliburn.Micro)项目框架的更多相关文章

  1. MVVM Caliburn.Micro学习记录

    wpf中MVVM一直用的自己写的框架,最近试了试Caliburn.Micro. Caliburn.Micro可以通过x:name来进行属性和事件绑定. 比如 <Button x:Name=&qu ...

  2. Caliburn.Micro 项目文档(翻译):Screens, Conductors and Composition

    原文地址(项目说明文档):[Documentation  Screens, Conductors and Composition]http://caliburnmicro.codeplex.com/w ...

  3. WPF 使用Caliburn.Micro 多线程打开窗口

    我们都知道在WPF里面用多线程打开一个窗口很简单.如下 public void ClickMe(object sender) { Thread newWindowThread = new Thread ...

  4. ViewModel从未如此清爽 - 轻量级WPF MVVM框架Stylet

    Stylet是我最近发现的一个WPF MVVM框架, 在博客园上搜了一下, 相关的文章基本没有, 所以写了这个入门的文章推荐给大家. Stylet是受Caliburn Micro项目的启发, 所以借鉴 ...

  5. Caliburn.Micro 杰的入门教程1(翻译)

    Caliburn.Micro 杰的入门教程1(原创翻译)Caliburn.Micro 杰的入门教程2 ,了解Data Binding 和 Events(翻译)Caliburn.Micro 杰的入门教程 ...

  6. 从0到1:使用Caliburn.Micro(WPF和MVVM)开发简单的计算器

    从0到1:使用Caliburn.Micro(WPF和MVVM)开发简单的计算器 之前时间一直在使用Caliburn.Micro这种应用了MVVM模式的WPF框架做开发,是时候总结一下了. Calibu ...

  7. Caliburn.Micro(MVVM框架)

    一.首启窗体设置 1. 创建一个新的WPF应用程序并添加NuGet包:Caliburn.Micro 2. 删除项目自带的主窗口文件MainWindow.xaml 3. 在App.xaml项目文件中,删 ...

  8. WPF MVVM(Caliburn.Micro) 数据验证

    书接前文 前文中仅是WPF验证中的一种,我们暂且称之为View端的验证(因为其验证规是写在Xaml文件中的). 还有一种我们称之为Model端验证,Model通过继承IDataErrorInfo接口来 ...

  9. 【整理总结】代码沉淀 - Caliburn.Micro - MV*模式短小精悍的框架

    Caliburn.Micro - Xaml made easy. web: https://github.com/Caliburn-Micro/Caliburn.Microdocument: http ...

随机推荐

  1. Mac上自带的Apache介绍

    Mac 自动Apache,无须再安装,默认的Apache地址是: /private/etc/apache2 一. Apache基本操作 1. 启动:sudo apachectl start 2. 查看 ...

  2. 把office文档转换为html过程中的一些坑

    之前和我们项目的团队一起酝酿了一个项目,公司的业务文档技术文档比较多,但都比较分散,虽然通过FTP或其他方式聚合起来了,但感觉还是不够方便. 另外公司每次都来新员工,新员工都需要一些培训,比较耗时,比 ...

  3. yii2的分页和ajax分页

    要想使用Yii分页类第一步:在控制器层加载分页类 use yii\data\Pagination;第二步: 使用model层查询数据,并用分分页,限制每页的显示条数$data = User::find ...

  4. 嵌入式Linux学习入门:控制LED灯

    记录自己linux学习过程,让自己能够一直坚持下去 1.原理图分析: nLED_1, nLED_2, nLED_4, 给低电平则对应LED灯亮,高电平则对应LED灯灭, S3C2440芯片GPF4-G ...

  5. js中的 || 与 && 运算符 的使用

    &&和||总是傻傻分不清,在这里详细记录一下吧.也给你们分享一下. 表达式a && 表达式b :  计算表达式(或者函数)a的运算结果, 如果为 True, 执行表达式 ...

  6. 浩瀚技术团队... 安卓智能POS移动PDA开单器 开单器 进销存系统 进销存系统

    浩瀚技术团队... 智能POS移动PDA开单器 开单器 进销存系统 进销存系统 点餐 会员管理 会员管理 深度解读 手机APP移动办公到底是什么? 快速打单POS·不仅仅是快那么简单!  

  7. Lattice Codes

    最近在做的一些关于lattice codes的工作,想记录下来. 首先,我认为lattice coding是一种联合编码调制技术,将消息序列映射到星座点.其中一个良好的性质是lattice point ...

  8. Spring Cloud 统一配置

    http://blog.csdn.net/catoop/article/details/50955949

  9. 16-1-27---图解HTTP(02)

    图解HTTP第四章 返回结果的HTTP状态码    HTTP状态码负责表示客户端HTTP请求的返回结果.标记服务器端的处理是否正常.通知出现错误等工作.4.1状态码告知从服务器端返回的请求结果     ...

  10. bfrd collector性能排查

     1.2.09上昨天timeout在18点23分-22点10分 2.检测2.17网卡流量,sar -f /var/log/sa/sa06 -n DEV,发现这段时间刚好是rxpck/s超过6400. ...