We've divided up the project, and I have selected a new (and exciting?) role for myself: the UI developer. Web UI, that is.
Taking a look around at popular sites, I can tell you already that I need to learn all about making good use of AJAX. Let me attempt to define it, based of course on an acquaintance of less that three weeks.
Traditional ASP and ASP.NET sites are heavy on the server-side processing. For any event you want to handle, the page needs to post back to the server and be loaded again. If your page is large, that's a lot of work. There are ways to pare down on page size (by making only the necessary controls ViewStateEnabled, for one thing), but the bottom line is a page reload for every click of a button. This means slow loading, flickering, and a choppy user experience.
Popular sites are developed by people who know what their audience wants. And while I am not yet a developer of a popular site, I can tell you right now what my audience wants: a site that loads quickly and that doesn't flicker. (Or hang up. Or crash their browser. More on those in a minute.)
Enter AJAX, a technology that was available as an add-in in Visual Studio 2005 and is a charter member of Visual Studio 2008. With AJAX, you can integrate Javascript asynchronous event handling into your page. The Javascript handlers asynchronously call server-side functions (exposed via .asmx web service or WCF - and one other method, for another post). The user continues interacting with a living, breathing page while the Javascript's spare thread waits for a response from the server; when the response arrives, the main thread updates the page accordingly and all is well. Mostly.
Note that I said the handlers asynchronously call server-side functions. The call is asynchronous; the server-side functions are not necessarily. What does this mean to my end-user? What does this mean to me?
The trouble comes in when the server response takes a long time. If many requests come in, and enough of them are taking a long time, then my server will run out of threads and my site will hang up. (Remember what I said? My users won't want that.)
The solution, my friends, is easier said than done: implement asynchronous calls where appropriate on the server side. For example, if my service function is doing I/O with the data store, the call to the DAL should be asynchronous. That way, the thread working on that service call can sleep instead of "busy waiting" and free itself up for another service call (maybe one that doesn't need any heavy I/O).
Sounds great in theory. What about in practice?
I think I'll go practice...
Showing posts with label PL. Show all posts
Showing posts with label PL. Show all posts
09 September 2009
02 July 2009
Pile on the layers
Here's a quote from MSDN:
"Most ASP.NET data source controls, such as the SqlDataSource, are used in a two-tier application architecture where the presentation layer (the ASP.NET Web page) communicates directly with the data tier (the database, an XML file, and so on)."
This is a cute way of saying that all those nice data-bound ASP.net controls - the ones that are supposed to take a data source and then do all the work of Selecting, Inserting, Updating, and Deleting (ie, CRUD) for you - will not work in a 3-layered structure.
That was the bad news, except that we knew it all along.
Here comes the good news:
"The ObjectDataSource works with a middle-tier business object to select, insert, update, delete, page, sort, cache, and filter data declaratively without extensive code."
http://msdn.microsoft.com/en-us/library/9a4kyhcx.aspx
So what do we need to do in order to get the data-sourced controls to work with an ObjectDataSource and, by extension, a BL and DAL?
Creating an ObjectDataSource Control Source Object has some answers. We need to define a stateless class (no non-static members) to provide CRUD logic for the data to populate the data-bound control on our form. Optionally, this class can also provide functions to filter the data and sort it. Then, using the (very handy) wizard provided by the ObjectDataSource, we select the class with the CRUD functions and identify the parameters it needs to preform Select.
Very well, but what about the parameters for Insert, Update, and Delete?
We can define another class to represent a record/row in our data schema. (The TypeName property of the ObjectDataSource must be set to this class.) All properties of the class will be polled (by reflection, one presumes) in order to fill the data-sourced control, and will be filled in return for the Update function. By setting the ConflictDetection property of the ObjectDataSource, we can even decide how updates should be done:
OverwriteChanges will simply fill an object with the new values and pass it to the Update function.
CompareAllValues will fill two objects: the first with the old values, the second with the new, and pass both to the Update function.
Two items of note:
1. The wizard will only work if your latest working build contains all the classes and functions you want to use! In other words, Build your project before running the wizard.
2. The CRUD functions I'm describing here are in my BL. They themselves do NOT do the actual persistence to the DB; rather they massage the data as appropriate and pass it in the appropriate format to the DAL, which does the real work.
"Most ASP.NET data source controls, such as the SqlDataSource, are used in a two-tier application architecture where the presentation layer (the ASP.NET Web page) communicates directly with the data tier (the database, an XML file, and so on)."
This is a cute way of saying that all those nice data-bound ASP.net controls - the ones that are supposed to take a data source and then do all the work of Selecting, Inserting, Updating, and Deleting (ie, CRUD) for you - will not work in a 3-layered structure.
That was the bad news, except that we knew it all along.
Here comes the good news:
"The ObjectDataSource works with a middle-tier business object to select, insert, update, delete, page, sort, cache, and filter data declaratively without extensive code."
http://msdn.microsoft.com/en-us/library/9a4kyhcx.aspx
So what do we need to do in order to get the data-sourced controls to work with an ObjectDataSource and, by extension, a BL and DAL?
Creating an ObjectDataSource Control Source Object has some answers. We need to define a stateless class (no non-static members) to provide CRUD logic for the data to populate the data-bound control on our form. Optionally, this class can also provide functions to filter the data and sort it. Then, using the (very handy) wizard provided by the ObjectDataSource, we select the class with the CRUD functions and identify the parameters it needs to preform Select.
Very well, but what about the parameters for Insert, Update, and Delete?
We can define another class to represent a record/row in our data schema. (The TypeName property of the ObjectDataSource must be set to this class.) All properties of the class will be polled (by reflection, one presumes) in order to fill the data-sourced control, and will be filled in return for the Update function. By setting the ConflictDetection property of the ObjectDataSource, we can even decide how updates should be done:
OverwriteChanges will simply fill an object with the new values and pass it to the Update function.
CompareAllValues will fill two objects: the first with the old values, the second with the new, and pass both to the Update function.
Two items of note:
1. The wizard will only work if your latest working build contains all the classes and functions you want to use! In other words, Build your project before running the wizard.
2. The CRUD functions I'm describing here are in my BL. They themselves do NOT do the actual persistence to the DB; rather they massage the data as appropriate and pass it in the appropriate format to the DAL, which does the real work.
29 June 2009
Not a member? Join today!
הגיע הזמן להפיק גירסה ראשונית לממשק משתמש. לאפליקציה אינטרנטית כמו שלנו, צריך לשאול: איך נטפל בזיהוי משתמשים, דוגמת רישום וכניסה למשתמש מוכר?
ASP.net
אמור לטפל בנושאים כאלה עם מה שנקרא "חברות" (תרגום
.(membership
אם המתכנת הוא אצלן (זה בעצם יכול להיות דבר טוב) אז סביבת הפיתוח יכול להפיק לו מסד נתונים מוסתר בשם
aspnetdb.mdf
בתיקיית ה
App_Data,
ודרך קריאות למחלקה מוסתרת שומרת נתונים לתוכו. דף לוקלי פותחים ישיר מהתפריט של סביבת הפיתוח שנותן לנהל את המשתמשים המוכרים כבר בזמן תכנון.


משפחת פקדים
login
שמגיע מוכן עם
.NET 3.5
משתמשים בכל זה באופן ישיר. ומהקוד שלך, תוכל בקלות לבדוק האם המשתמש הנוכחי נכנס למערכת רשמי כמשתמש מוכר ופרטים נוספים מהסטטוס ה"חברתי" שלו.
מה בזה לא טוב לנו?
משפחת הפקדים הזו מבוססת על הכלת מסד הנתונים המוסתרת שם בדיוק בתוך שכבת הממשק משתמש, גבר שמונע ממך למשוך נתוני משתמש ממסד הנתונים שלך. בנוסף, זה שובר את מודל ה3 שכבות. סה"כ, לא בתוכניות המקוריות שלנו.
אפשר לתת לספק החברות (מחלקה שמנהלת חברות) מאיפה למשוך את הנתונים... אבל אז אתה משנה את ההגדרות לספק החברות שנמצאות ב
machine.config
ע"י הוספת עצמים ל
web.config
ואז מבנה הטבלאות שלך חייב להתאים לדרישות של ספק החברות המוכן. ויתר על כן, מסד הנתונים שלך חייב להימצא בשכבת ממשק המשתמש. עדיין לא 3 שכבות, עדיין לא מצא חן בעינינו.
במחיר הרבה עבודה מיותרת, נוכל לממש ספק חברות משלנו וגם (הודו לה') לשמור על מבנה ה3 שכבות וגם להשתמש בפקדים המוכנים. זה מוצא חן בעינינו, בגלל שלבסוף רוב הקוד שאנחנו כותבות לספק חברות שלנו מהווה פונקציונליות נחוץ כדי ליצור אתר אינטרנט עם זיהוי משתמשים מספקת. ולאור חוסר נסיון שלנו בזיהוי משתמשים, נשמח לקבל הגדרות קשיחות ממיקרוסופט.
נקודה אחרונה: פקדים ממשפחת
login
שוברות את
MVC.
אבל המטרה של דגם תכנון הוא להיות כלי, לא להיות מחסום - אז אם צריך, נשבור!
--------------------------------------------
The time has come to produce a version of the UI. For a web application like ours, we must answer the question: how do we handle user authentication (eg, registration and login) ?
ASP.net is designed to deal with these issues with what it calls "membership".
If the programmer is really lazy (this can be a good thing), ASP.net will generate an invisible database called aspnetdb.mdf in your App_Data folder and invisibly call on a class to persist to that database. A (local) web page that opens directly from the menu in Visual Studio allows you to manage the users from this database at design time.


The Login family of controls provided by ASP.net plug directly into this system. And from your code, you can easily check if the current user is logged in and other details of his "membership" status.
What about this don't we want?
The Login family of controls provided by ASP.net are based on inclusion of the (invisible) database right there in your UI layer, which means that user data is not coming from your own database. Additionally, this is not in keeping with the 3-layered look. Altogether, not part of our original plans. You can tell the membership provider where its database is... but then you're overriding the default provider datastore defined in machine.config by adding elements to web.config, and then your table structure has to be exactly what the canned membership provider is expecting. And, of course, the membership provider is in the UI, so your database must be there, too. Still not 3 layers, still pretty evil.
For the price of lots of extra work, we can implement our own membership provider class and (oh, joy) still preserve the 3 layers AND use Microsoft's Login controls. This is good, because ultimately the vast majority of the code we're writing for our customized membership provider is functionality we need in order to have a website with sufficient authentication. And, as we have little to no experience with authentication, if Microsoft is dictating what our authentication class needs to support, we're more likely to reach our destination.
A final point: the Login controls will never work with MVC. But MVC is a tool for us, not a prison - so when it serves us to break it, we will!
ASP.net
אמור לטפל בנושאים כאלה עם מה שנקרא "חברות" (תרגום
.(membership
אם המתכנת הוא אצלן (זה בעצם יכול להיות דבר טוב) אז סביבת הפיתוח יכול להפיק לו מסד נתונים מוסתר בשם
aspnetdb.mdf
בתיקיית ה
App_Data,
ודרך קריאות למחלקה מוסתרת שומרת נתונים לתוכו. דף לוקלי פותחים ישיר מהתפריט של סביבת הפיתוח שנותן לנהל את המשתמשים המוכרים כבר בזמן תכנון.
login
שמגיע מוכן עם
.NET 3.5
משתמשים בכל זה באופן ישיר. ומהקוד שלך, תוכל בקלות לבדוק האם המשתמש הנוכחי נכנס למערכת רשמי כמשתמש מוכר ופרטים נוספים מהסטטוס ה"חברתי" שלו.
מה בזה לא טוב לנו?
משפחת הפקדים הזו מבוססת על הכלת מסד הנתונים המוסתרת שם בדיוק בתוך שכבת הממשק משתמש, גבר שמונע ממך למשוך נתוני משתמש ממסד הנתונים שלך. בנוסף, זה שובר את מודל ה3 שכבות. סה"כ, לא בתוכניות המקוריות שלנו.
אפשר לתת לספק החברות (מחלקה שמנהלת חברות) מאיפה למשוך את הנתונים... אבל אז אתה משנה את ההגדרות לספק החברות שנמצאות ב
machine.config
ע"י הוספת עצמים ל
web.config
ואז מבנה הטבלאות שלך חייב להתאים לדרישות של ספק החברות המוכן. ויתר על כן, מסד הנתונים שלך חייב להימצא בשכבת ממשק המשתמש. עדיין לא 3 שכבות, עדיין לא מצא חן בעינינו.
במחיר הרבה עבודה מיותרת, נוכל לממש ספק חברות משלנו וגם (הודו לה') לשמור על מבנה ה3 שכבות וגם להשתמש בפקדים המוכנים. זה מוצא חן בעינינו, בגלל שלבסוף רוב הקוד שאנחנו כותבות לספק חברות שלנו מהווה פונקציונליות נחוץ כדי ליצור אתר אינטרנט עם זיהוי משתמשים מספקת. ולאור חוסר נסיון שלנו בזיהוי משתמשים, נשמח לקבל הגדרות קשיחות ממיקרוסופט.
נקודה אחרונה: פקדים ממשפחת
login
שוברות את
MVC.
אבל המטרה של דגם תכנון הוא להיות כלי, לא להיות מחסום - אז אם צריך, נשבור!
--------------------------------------------
The time has come to produce a version of the UI. For a web application like ours, we must answer the question: how do we handle user authentication (eg, registration and login) ?
ASP.net is designed to deal with these issues with what it calls "membership".
If the programmer is really lazy (this can be a good thing), ASP.net will generate an invisible database called aspnetdb.mdf in your App_Data folder and invisibly call on a class to persist to that database. A (local) web page that opens directly from the menu in Visual Studio allows you to manage the users from this database at design time.
What about this don't we want?
The Login family of controls provided by ASP.net are based on inclusion of the (invisible) database right there in your UI layer, which means that user data is not coming from your own database. Additionally, this is not in keeping with the 3-layered look. Altogether, not part of our original plans. You can tell the membership provider where its database is... but then you're overriding the default provider datastore defined in machine.config by adding elements to web.config, and then your table structure has to be exactly what the canned membership provider is expecting. And, of course, the membership provider is in the UI, so your database must be there, too. Still not 3 layers, still pretty evil.
For the price of lots of extra work, we can implement our own membership provider class and (oh, joy) still preserve the 3 layers AND use Microsoft's Login controls. This is good, because ultimately the vast majority of the code we're writing for our customized membership provider is functionality we need in order to have a website with sufficient authentication. And, as we have little to no experience with authentication, if Microsoft is dictating what our authentication class needs to support, we're more likely to reach our destination.
A final point: the Login controls will never work with MVC. But MVC is a tool for us, not a prison - so when it serves us to break it, we will!
Labels:
3-layered,
ASP.net,
authentication,
Login,
membership,
PL,
Visual Studio
Subscribe to:
Posts (Atom)