项目介绍:
项目名称叫Workflow, 是为一家在荷兰的呼叫中心客户化定制开发一款帮助他们管理工作流的系统。这个系统采用Domain Driven Design作为整个项目的总体设计方案。商业逻辑(business logic)在Domain model实现,Domain model用POCO(plain old c# object)实现,Domain model凭借fluent nhibernate map到数据库。Web部分采用ASP.NET MVC 2.0,StructureMap做为IoC container, 所以在controller里面就可以方便的使用接口I*whatever*Service来inject服务层。 当然了,项目中用到Messaging的部分是借用NserviceBus实现的。
因为整个系统中频繁用到给用户发邮件的功能,所以下面我就给大家介绍一下如果用NServiceBus实现Email messaging.
0. 在MVC project Web.config文件中,添加下面的配置, 主要目的是设置发送出去的message到达的终点站。
1
<
UnicastBusConfig
>
2
<
MessageEndpointMappings
>
3
<
add Messages
=
"
Workflow.Messages.Email.EmailMessage, Workflow.Messages
"
Endpoint
=
"
EmailQueue
"
/>
4
</
MessageEndpointMappings
>
5
</
UnicastBusConfig
>
6
1. 在Controller constructor 里面inject IEmailService
1
public
AdministratorsController(
IUserMailer userMailer)
2
{
3
this
.userMailer
=
userMailer;
4
}
2. 大家注意第10行,当新添加一个administrator之后,调用userMailer服务,来给这个新添加的管理员发送密码。
1
public
Url Post(AddAdministratorViewModel model)
2
{
3
if
(
!
ModelState.IsValid)
4
{
5
return
model;
6
}
7
8
var administrator
=
administratorFactory.Create(model.UserName, model.Email);
9
adminRepository.Add(administrator);
10
userMailer.SendPasswordNotification(administrator);
11
12
return
new
AdministratorUrl { Administrator
=
administrator };
13
}
3. 接下来在ApplicationService层里,UserMailer类继承IUserMailer, 同样在UserMailer constructor里面 inject IBus. IBus是NServiceBus的接口。
1
public
UserMailer(IBus bus)
2
{
3
this
.bus
=
bus;
4
}
4. 第8行创建一个新的EmailMessage对象, 第9行用bus 发送这个对象。
1
public
void
SendPasswordNotification(User user)
2
{
3
if
(user
==
null
)
4
{
5
throw
new
ArgumentNullException(
"
user
"
);
6
}
7
8
var email
=
new
EmailMessage("from", "to", "title"
, "body");
9
bus.Send(email);
10
}
5. EmailMessage 类需要继承IMessage, IMessage是NServiceBus的一个接口,表明这个类符合NServiceBus对Message的定义,同时可以被NServiceBus处理。
1
public
class
EmailMessage : IMessage
2
{
3 // EmailMessage implementation goes here;
4
}
6. 最后一个环节就是在Solution中创建一个新的class library, 可以作为background service来实际发送邮件。在实现这个class library的时候,有基本上有3个方面需要注意:
1). App.config, 第4, 5, 7三行是特别用来配置NServiceBus. 在MsmqTransportConfig这一行,确保InputQueue是你在第0步骤中设定的Message要达到终点站的名字
1
<?
xml version
=
"
1.0
"
?>
2
<
configuration
>
3
<
configSections
>
4
<
section name
=
"
MsmqTransportConfig
"
type
=
"
NServiceBus.Config.MsmqTransportConfig, NServiceBus.Core
"
/>
5
<
section name
=
"
Logging
"
type
=
"
NServiceBus.Config.Logging, NServiceBus.Core
"
/>
6
</
configSections
>
7
<
MsmqTransportConfig ErrorQueue
=
"
error
"
InputQueue
=
"
EmailQueue
"
MaxRetries
=
"
5
"
NumberOfWorkerThreads
=
"
1
"
/>
8
<
startup
>
9
<
supportedRuntime sku
=
"
.NETFramework,Version=v4.0
"
version
=
"
v4.0
"
/>
10
</
startup
>
11
</
configuration
>
2). MessageEndPoint.cs, 这个类继承了NServiceBus的几个接口, IConfiureThisEndpoint (表明这个类是终点站的配置类), AsA_Server(表明这个终点站是个服务器), IWantCustomerInitialization(表明我们需要自己的container 和 serializer)
1
public
class
MessageEndpoint : IConfigureThisEndpoint, AsA_Server, IWantCustomInitialization
2
{
3
public
void
Init()
4
{
5
Configure.With()
6
.StructureMapBuilder(ObjectFactory.Container)
7
.XmlSerializer();
8
}
9
}
3). EmailHandler.cs: 当EmailMessage 这个类型的message到达中间站的时候,我们要对这个message的操作在此类中实现。在本例中,我们首先获得一个SmtpClient的实例,然后用我们的EmailMessage来创建一个System.Net.Mail.MailMessage的实例mail,最后用smtpclient将这个mail发送。搞定!
1
public
class
EmailHandler : IHandleMessages
<
EmailMessage
>
2
{
3
public
void
Handle(EmailMessage message)
4
{
5
try
6
{
7
var client
=
new
SmtpClient();
8
var htmlBody
=
"
blah
"
;
9
var mail
=
new
MailMessage(message.From, message.To);
10
11
client.Send(mail);
12
}
13
catch
(SmtpFailedRecipientsException)
14
{
15
//
mail cannot be sent due to recipient specific error
16
}
17
}
18
}
当你实现了上面六个环节之后,在visual studio中设定"Set Startup Project", 选中新创建的class library。接下来F5, 你会发现除了正常的MVC项目启动之外,还有一个background application 也会同时启动。当你在系统中新创建一个管理员时,NServiceBus将向你的管理员发送他首次登陆密码。
希望这篇文章对大家在了解和使用NSerivecBus搭建SOA类型的项目时,有一定的帮助。期待看到越来越多的人喜欢上NServiceBus。
当一个程序员面临太多选择的时候
摘要: 转眼间已经五天没有写博客,没有读/写代码了,人长大后为什么时间就过的这么快。记得小时候盼个周末放假都是那么的漫长。Anyway, 今天跟大家探讨一个问题:当程序员面临太多选择的时候。 不知道其它职业如何,但作为一个程序员,我总是感觉到自己每天都需要做很多很多的选择。有些选择我自认为选的有根有据,有些选择我只能是出自自己的直觉(gut feelings),但也有些选择是实在不知道选择什么好但期限又...
阅读全文
posted @
2010-11-25 22:14 lipu_paul 阅读(2868) |
评论 (14)
编辑
庖丁解ASP.NET MVC内部运行流程
摘要: 跟大家分享两张ASP.MVC的内部运行流程图,作者都是Steve Sanderson,上面这张是07年MVC还未正式发布之前做成的流程图,虽然较老但是放到今天大部分仍然基本适用(注意:图中有些部分已经过期,但是因为比较详细全面,也贴上来了)。下面那张是09年的,贴上来的理由是图中详细的表出MVC框架里哪些部分是可以被拓展(extend)的, 比如说你可以用Cusotom route handler...
阅读全文
posted @
2010-11-19 07:09 lipu_paul 阅读(2419) |
评论 (11)
编辑
.Net TDD我用Machine.Specification
摘要: 昨天碰巧看到Professional ASP.NET MVC 2这本书里面在介绍如何使用TDD进行开发,里面有这样一段代码,[代码]这段代码让我意识到自己在项目中使用Machine.Specification这个TDD的测试框架的一些优点,跟大家分享。如果使用Machine.Specification, 上面这段代码可以可以这样来写:[代码] 从行数上来讲使用Machine.Specificat...
阅读全文
posted @
2010-11-17 20:13 lipu_paul 阅读(1506) |
评论 (6)
编辑
轻轻松松SOA: NServiceBus
摘要: 上周跟一位猎头在google talk上聊了几句,被问道有没有WCF, WF的经验,汗!对于WCF, WF,没有任何经验,但是这并不代表着我对SOA没有任何应验,其实去年一年,我们都是在用NerviceBus作为实现SOA的工具。百度了一下,发现有个园友似水流年已经写过一篇介绍NServiceBus的文章,“NServiceBus---最流行的开源企业服务总线 for .Net&rdq...
阅读全文
posted @
2010-11-16 20:05 lipu_paul 阅读(2244) |
评论 (6)
编辑
.Net程序员面试 中级篇 (回答Scott Hanselman的问题)
摘要: 继《.Net 程序员面试 C# 语言篇 (回答Scott Hanselman的问题)》跟《.Net程序员面试 每个人都应知道篇 (回答Scott Hanselman的问题)》之后,今天回答Scott Hanselman在他清单上列出的“中级.Net程序员应该知道的问题”。1. 面向接口,面向对象,面向方向的编程的不同 (Describe the difference bet...
阅读全文
posted @
2010-11-14 05:59 lipu_paul 阅读(3756) |
评论 (10)
编辑
.Net程序员面试 每个人都应知道篇 (回答Scott Hanselman的问题)
摘要: 昨天回答了Scott Hanselman在他清单上关于C#那部分的题目,.Net 程序员面试 C# 语言篇 (回答Scott Hanselman的问题),今天接着回答他在清单上列出的"每个写代码的人都应该知道"部分的题目。1. 描述线程跟进程的区别 (Describe the difference between a Thread and a Process?)进程是指处于运行状态中的程序, 例如...
阅读全文
posted @
2010-11-12 20:42 lipu_paul 阅读(3092) |
评论 (8)
编辑
.Net 程序员面试 C# 语言篇 (回答Scott Hanselman的问题)
摘要: 过去几年都在忙着找项目,赶项目,没有时间好好整理深究自己在工作中学到的东西。现在好了,趁着找工作的这段空余时间,正好可以总结和再继续夯实自己的.Net, C#基本功。在05年的时候,Scott Hanselman(微软的一个Principal Program Manager)在他的博客上列出了一张清单, 清单上是关于"一个好的.Net程序员应该知道的东东What Great .NET Develo...
阅读全文
posted @
2010-11-12 05:33 lipu_paul 阅读(4876) |
评论 (38)
编辑
为什么程序员不会编程?
摘要: 人生真的很有意思,三年前我坐在面试官的位置上,面试别的程序员,现在我坐在程序员的位置上,等待被别人面试。 三年前我跟朋友合作在厦门开始创业,做对欧美的软件外包开发。当时困扰我们最大的问题之一就是找不到会编程的程序员。往往收到四,五十份简历,到最后只有一两个应聘者能通过我们的编程测试。其实测试的题目也不难,像bubble sort之类的问题。现如今,从荷兰回来,需要找一份工作,却发现找到一家好的公...
阅读全文
posted @
2010-11-10 22:28 lipu_paul 阅读(1093) |
评论 (27)
编辑
ASP.NET MVC 3 Release Candidate 发布喽
摘要: ScottGu在其blog上宣布ASP.NET MVC 3 Release Candidate发布的消息。你可以在这里下载最新的mvc3。 在ScottGu博客中提到MVC 3的一些新功能:Razor View Engine 在Visual Studio中Intellisense的支持NuGet Package Manager. 非常像ruby的 gem install. 虽然自己还没有用过Nu...
阅读全文
posted @
2010-11-10 19:27 lipu_paul 阅读(115) |
评论 (0)
编辑
回国了,在网上找个窝
摘要: 好久之前就想开始写blog了,可是久久都没有行动,总是忙着学习新鲜的东西,在自己的本本上搭建新的环境。偶尔有些心得体会的时候,也是草草地放在自己的邮箱里,懒得认真地整理成文章,拿出去跟大家分享。最近回过头来,反思一下,也觉得自己有点自私。还好,今天悔改,为时不晚。从今天开始,我要尝试着在这里记录我在IT行业里的所见所闻,所思所想,所学所得。 这两天左右前后比较了一下csdn跟cnblogs, 感...
阅读全文
posted @
2010-11-10 18:51 lipu_paul 阅读(169) |
评论 (2)
编辑