System.Web.Mail -where does it fit in the CSLA model?

System.Web.Mail -where does it fit in the CSLA model?

Old forum URL: forums.lhotka.net/forums/t/3556.aspx


Lyndon posted on Monday, September 17, 2007

Hi,

In the spirit of keeping most of the business rules in the buiness objects as part of the CSLA framework, I am trying to use the System.Web.Mail functionality in ASP.NET 2.0 to send an email to a user indicating that a requests they have submitted has changed status.

I currently identify that  change in status by looking for certain values in combination in my business object which inherits BusinessBase.

Normally you need to include an 'imports' command in your code. When you do that in the object, it understands importing 'System.Web' but does not give the option of 'System.Web.Mail'  .

If I do the imports at the aspx page level code and look to action the email as a change in the value of a dropdown, it understands Systems.Web.Mail.

Perhaps its a dumb question, but why is the above the case? Should automatic creation/sending of emails be located in the business object or the web page?

skagen00 replied on Monday, September 17, 2007

System.Web.Mail does appear to be in System.Web.dll. So you need to make sure you are add a reference to System.Web for the project you're adding this logic to. You probably have another assembly referenced that has elements in the System.Web namespace, which is why you can say "using System.Web" but not "using System.Web.Mail". For mail you need System.Web.dll.

For sending the emails - think about the use cases - if I change status, I want an e-mail to be sent. It's business logic - you're going to want this behavior within the business layer.

Chris

 

tetranz replied on Monday, September 17, 2007

Not directly related to your question but System.Web.Mail is obsolete and replaced by System.Net.Mail.

ajj3085 replied on Monday, September 17, 2007

I thought it would be, but I've since changed my outlook.  It led to problems, such as how do you test that the mail is being sent in unit testing?  Do you want an email sent every run of the test?

I'm now of the school of thought that the email should be considered part of the presentation layer, possibly using business objects to determine who gets an email and the data it would contain.

Normally, I'd advocate Sql Server Notification Services, but unfortunately this is going away in Sql Server 2008.  Supposedly, you can do the same thing via reporting services... but I haven't looked into that. 

HTH
Andy

josh.kodroff replied on Monday, September 17, 2007

My personal favorite OO principle is encapsulation. 

To understand why you shouldn't import System.Web.Mail (or System.Net.Mail) in your business logic layer, think about this:  What would you do if you web app became a Windows app?  Maybe sending an email would no longer be appropriate. 

Whichever object is saving the status-changing data to the DB should be raising an event that's handled by the UI or some other layer. 

Lyndon replied on Monday, September 17, 2007

In my example above, I am actually wanting an email to be sent regardless of whether it is a windows based client accessing the object or a web based client. The choices I felt were  to either send the email when a dropdownlist value was selected in the client application or when the value changed in the business object as a result of the the value being selected in the dropdown list

Thanks guys for all the above responses

skagen00 replied on Tuesday, September 18, 2007

Just to follow up -

I think especially given your notes about it occuring through Web or Windows - I think it belongs in the business layer. I do not think that "side effects of unit testing" should affect the architecture of your app.

With respect to including System.Web.dll or what have you in a business class library, it has nothing to do with breaking encapsulation. Zero, nada. Will most people find a need to include System.Web in their business class library? Probably not. But we happen to use the ASP.Net Membership and Role API as our standard authentication and authorization for our application - we're building a Web application but there's no reason why we need to have a separate security scheme for Windows (we wouldn't want that!)

In the case where behavior varies between UI's, it depends on specs as to how to proceed - but for example Caching will work differently in Web than Windows for us - in this situation, we have leveraged the provider design and happen to have a WebCacheProvider for our current UI (Web) understanding that what we do for Web is not applicable for Windows. But our business library invokes the CacheManager - part of the business library (which looks at the config file to determine which CacheProvider to leverage).

Chris

 

ajj3085 replied on Tuesday, September 18, 2007

skagen00:
I think especially given your notes about it occuring through Web or Windows - I think it belongs in the business layer. I do not think that "side effects of unit testing" should affect the architecture of your app.


The side effect of testing brings to the surface though that this probably doesn't belong in the business layer.  What happens when load on the library increases?  More and more time is now spent sending emails.  What happens if the network or mail server is done?  Does the business object abort the entire transaction?  Nevermind the fact that it will block while its waiting for a timeout, further hurting performance.

A simple email may not seem like a big deal, but it can get out of hand, and become a big problem in the business layer.  Remember, the email is presenting information... its part of the presentation layer.   Notification on data changes can be a big task, which was why Notification Services was developed.  Its just too bad nobody seemed to be using it.  Indifferent [:|]

skagen00 replied on Tuesday, September 18, 2007

I'm not sure what you mean about load - a sent e-mail is a sent e-mail. I sure hope it doesn't take a lot of effort to send e-mails because I would start to feel sorry about all these spammers. ;)

Sending an e-mail from the business layer doesn't need to be synchronous, too.

Bottom line is that if someone wants a "notification if a record has changed" - I don't want to be coding that accomodation in my Win UI, my Web UI, and Web Services UI.

Anyways, I think we'll have to agree to disagree here!

ajj3085 replied on Wednesday, September 19, 2007

skagen00:
I'm not sure what you mean about load - a sent e-mail is a sent e-mail. I sure hope it doesn't take a lot of effort to send e-mails because I would start to feel sorry about all these spammers. ;)


If you're talking about an app server, the server is spending more time sending emails, which can slow things down.  If done on the client side, your user will be waiting for the mail to be sent before the UI returns control to them.  I had my application sending an email when certain data changed on save, and it did slow things down quite a bit.  As my application needed to send more and more emails, things got more complex.  Especially when I had to send the same email when the same data was changed, but the change could happen in five different business objects.

skagen00:
Sending an e-mail from the business layer doesn't need to be synchronous, too.

True, but then you add complexity.  Do you have to handle the AsyncCompletedCallback?  I don't know, I can't find anything in the docs one way or another.  What happens if the sending fails, and the mail MUST be sent?  Do you retry?  You have to inform the user at some point.  A down mail server can cause a lot of problems.

skagen00:
Bottom line is that if someone wants a "notification if a record has changed" - I don't want to be coding that accomodation in my Win UI, my Web UI, and Web Services UI.

I agree!  That's why I advocated SSNS or I guess in Sql 2008, SSRS.  SSNS was great because it handled failures and automatically retried, was easily extensible, could handle digest or multicast delivery and a host of other things.   SSNS worked basically by running queries you define to detect changes in data, and then generated notifications based on that data.  No need to code anything into your application at all, SSNS handled it all for you.

skagen00:
Anyways, I think we'll have to agree to disagree here!

I suppose so; like I said, its unfortnate SSNS is being discontined, otherwise I'd suggest you check it out.

JoeFallon1 replied on Wednesday, September 19, 2007

I have a table in my DB where I store the data for emails that need to be sent.

Then I have a separate scheduled task which runs every 10 minutes (or whatever interval the client defines) which processes the records in this email table and sends them. This separates the 2 activities and the offline task is free to take as much time as it needs to talk to the mail server. The offline task can also log information about each email it sends - ncluding the fact that the mail server might be down.

Joe

 

ajj3085 replied on Wednesday, September 19, 2007

Joe, that's basically what SSNS does Wink [;)]

Curelom replied on Wednesday, September 19, 2007

I use a web service for sending emails which simplifies the async.  It isn't critical for my app if the email doesn't send.  I am intrigued by this SSNS though.  Are there any good articles out there on it?

Lyndon replied on Wednesday, September 19, 2007

I have same question- I havent found a whole lot of good documentation on notification services. Any one have any good leads?

ajj3085 replied on Thursday, September 20, 2007

Here is the home page:

http://www.microsoft.com/sql/technologies/notification/default.mspx

Here's a SqlMag article: http://www.sqlmag.com/Article/ArticleID/47143/sql_server_47143.html


As I said though, its not going to be around in 2008.  Supposedly Reporting Services can do the same thing, but I'm not sure. 

Copyright (c) Marimer LLC