最近做了一个软件,这个软件不是网站,但是与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. CPU状态信息us,sy,ni,id,wa,hi,si,st含义

    转自:http://blog.csdn.net/sasoritattoo/article/details/9318893 转自:http://fishermen.iteye.com/blog/1995 ...

  2. 安装ganglia

    安装ganglia 1.默认已经配置好相关的主机名和Ip地址映射关系 2.默认已经安装好ssh密码登陆 3.默认已经配置好yum源和相关网络配置(如hosts 可在墙外) 4.服务器端安装(除了yum ...

  3. POJ 2653 Pick-up sticks (线段相交)

    题意:给你n条线段依次放到二维平面上,问最后有哪些没与前面的线段相交,即它是顶上的线段 题解:数据弱,正向纯模拟可过 但是有一个陷阱:如果我们从后面向前枚举,找与前面哪些相交,再删除前面那些相交的线段 ...

  4. JS隐形数据类型转换注意事项

    alert('2'===2); //这个结果是false,首先三个等号要比较数据类型,字符串和整数不相等 alert('2'==2);    //这个结果是true,因为是两个等号,所以不会比较数据类 ...

  5. C# 4.0四大新特性代码示例与解读

    摘要:今天我们结合代码实例来具体看一下C#4.0中的四个比较重要的特性. 之前的文章中,我们曾介绍过C#的历史及C# 4.0新增特性,包括:dynamic. 命名和可选参数.动态导入以及协变和逆变等. ...

  6. yarn关于app max attempt深度解析,针对长服务appmaster平滑重启

    在YARN上开发长服务,需要注意fault-tolerance,本篇文章对appmaster的平滑重启的一个参数做了解析,如何设置可以有助于达到appmaster平滑重启. 在yarn-site.xm ...

  7. three.js全景

    <!DOCTYPE html> <html lang="en"> <head> <title>three.js webgl - eq ...

  8. EditText限制小数点前后位数

    在EditText输入数字的时候,通常我们需要限制小数点前后位数.比如金额输入一般我们需要限制小数点后面最多2位.我们可以通过 TextWatcher 实现. public class MyWatch ...

  9. 关于AlertDialog.Builder(Context context)中所应传入的context

    错误报告: 10-20 14:34:46.565: E/AndroidRuntime(23098): FATAL EXCEPTION: main10-20 14:34:46.565: E/Androi ...

  10. 一键保存Feedly里的文章到有道笔记

    写在之前:今天升级了有道笔记3.5,发现有道笔记支持发邮件保存笔记了,所以就分享一下怎么通过IFTTT保存到有道笔记.因为IFTTT是外国货,所以一直没有有道笔记的频道,不过有了发邮件保存笔记的功能, ...