-
Re: Constructive Criticism
We'll get to naming conventions later. Create a class PlayerDAL.cs. Create a class PlayerBL.cs
In PlayerDAL.cs
static DataSet GetPlayers(int teamID)
{
//Call database
//Fill dataset
//Return dataset
}
In PlayerBL.cs
static List<Player> GetPlayers(Team team)
{
DataSet ds = PlayerDAL.GetPlayers(team.TeamID);
//Loop through dataset
//Create player objects
//Add to list
//Return list
}
From your page,
PlayerBL.GetPlayers(tm2);
OK, so that's one way. Another preference is to have the DAL method return List<Player> and have the BL class method deal with it or do any additional processing if required and then return List<Player>.
-
Re: Constructive Criticism
Hey,
To follow on from Mendhak's example, what I have done in the past is to return a List<PlayerDetails> from the DAL. This is essentially a direct copy of the fields in the Player table. My BL then works with a List<Player> which is the correctly formatted version of the Player object, perhaps with some additional fileds based on the results of the values pulled from the database, or some other factors.
Gary
-
Re: Constructive Criticism
I do that too. My DAL returns List<PlayerDetails>. Maybe I should have mentioned that first but you get the idea I hope...
-
Re: Constructive Criticism
Thanks Gary for the example link you provided but I don't think that i can use it right now since its level is too advance for my current skill.
Mend, thank you very much for all the examples you share, they're very useful for me and help me understand things much faster.
I'm just about to improve my code and extend it to data access and business logic, i will return with the result, in the meanwhile i want to ask something else:
for preference reasons, how do you usually write your logic classes, all the class in one file (e.g. WebSiteDAL/BL) or to separate every class to a single file?
-
1 Attachment(s)
Re: Constructive Criticism
Hey,
A picture says a thousand words....
Attachment 74956
Here you can see a logical separation between the code in the BL and the DAL.
Gary
-
Re: Constructive Criticism
Quote:
Originally Posted by
motil
Thanks Gary for the example link you provided but I don't think that i can use it right now since its level is too advance for my current skill.
I know it is quite daunting, but once you get over the initial "OMG what is going on", it all starts to make sense.
You will find examples of all the things we have been talking about in that sample. I would bookmark it, and come back to it when you get some time.
Gary
-
Re: Constructive Criticism
Thanks Gary!
I will get back to the sample code once i'll more time (and experience) .
-
Re: Constructive Criticism
so, i created a new class for the BLL, but when i tried to save it in any other place beside the App_Code Directory i can't create an instance of that class, why is that ?
-
Re: Constructive Criticism
That's because that is the directory meant for executable dll files.
The other way would be to add a class library project to your solution. Then add a reference to that project in your web project so that it can be used anywhere in your web project. This way you would separate it from your web pages (presentation layer).
-
Re: Constructive Criticism
Where exactly are you trying to save it? Within a folder in the App_Code Folder? If so, Visual Studio will have altered the Namespace for you slightly, so you will need to make sure you include the full namespace in order to instantiate it.
If this isn't the problem, can you provide more details? i.e. do you get an error?
Gary
-
Re: Constructive Criticism
I created two "normal" folders inside my project "DAL" and "BLL" I created a class for the BLL and saved it there, but it seems that you can't save classes outside the APP_CODE directory cause now i can't Create an instance of the class that stored inside the the BLL directory, i think that Pradeep supplied the answer but i'm not quite sure how to do this
-
Re: Constructive Criticism
Ah, I see. Yes, you will need to create them in the App_Code Folder, but there is nothing to stop you putting them in folders within the App_Code folder.
Further segregation would be to create them in their own class libraries. That is actually what you see in the screen shot that I posted before.
Gary
-
Re: Constructive Criticism
and how do i create class library ? i searched for this option couldn't found it
-
Re: Constructive Criticism
Ah, now, are you using Visual Web Developer?
Gary
-
Re: Constructive Criticism
nope, visual studio 2008 pro
-
1 Attachment(s)
Re: Constructive Criticism
Hmm, in which case, just do this.
Right click on your solution, and select Add | New Project, then select the following:
Attachment 74961
Gary
-
Re: Constructive Criticism
Thanks guys, worked like a charm!
-
Re: Constructive Criticism
Hey,
No probs. Happy to help.
Given the length of this thread, and some of the questions, might be worth breaking out any new questions into it's own thread.
Gary
-
Re: Constructive Criticism
Well, I believe that I'll have more questions about the n-tier concept and i think that all of the questions here are related to this subject in one way or another, people that new to this concept will have great start-up point because of this thread, i think that the info you guys supplied here is better then any other article i've seen on the net (for just understanding this concept and start using it).
but if you think i should open new thread i have not problem doing so :)
-
Re: Constructive Criticism
Hey,
This is always a hard one.
Sometimes long threads like this get quite involved, and it is easy to go off course with other lines of conversation, but you are right, there is lots of good information in this thread, so maybe we should keep going with it, and try to stick as closely to the main discussion as possible.
Gary
-
Re: Constructive Criticism
-
Re: Constructive Criticism
I usually create separate class library projects for each layer. You mentioned App_Code, which indicates that you're working with web site projects which may be the reason you can only add your .cs files to App_Code. I also prefer web application projects which is slightly different.
-
Re: Constructive Criticism
Hey,
I didn't mention this before, but now that Mend has brought it up, I also prefer the use of a Web Application, over a Web Site. Given that you are using the Professional version of Visual Studio, there is no reason that you can't use this.
There are even steps you can follow to do the conversion if you choose to:
http://msdn.microsoft.com/en-us/libr...76(VS.80).aspx
Gary
-
Re: Constructive Criticism
Hi, can i ask what are the advantage of using web application ?
-
Re: Constructive Criticism
Hey,
Rather than repeat the content here, I thought I would just give you a link :)
http://reddnet.net/code/asp-net-web-...roject-part-2/
Gary
-
Re: Constructive Criticism
Thanks Gary, that article was very helpful!
-
Re: Constructive Criticism
Ok, so in my data access layer while i'm filling my list of object, let's say i have a column data represent DateTime and i need to check if it as a valid date value, where do i do the calculations ?, should i do it right on the spot (inside the loop) or should i call a method that placed in my business logic layer and do the calculation from there ?
-
Re: Constructive Criticism
One more question:
Inside my BLL/DAL i can't use the Trace.Warn methods, how do you guys debug what going on in those layers?
-
Re: Constructive Criticism
One More :)
I have this line up of methods calls inside my presentation layer all of those methods are placed inside my BLL, each of of those methods call to other methods that placed inside my DAL which do some kind of database operation, the target of this process is to
delete old team and add new team instead.
Code:
// Getting list of SiteSetting (return 1 item)
List<SiteSetting> lstSiteSetting = siteSetting.GetAllFromSiteSetting();
// Getting list of UsersDetails (return 1 item)
List<UsersDetails> lstUsersDetails = usersDetails.GetAllFromUsersDetailsByRecordID(TeamID);
// Increasing SiteSetting TeamID by 1
siteSetting.IncreaseByOneSiteSettingTeamID();
// Getting list of empty (none user) teams (Limiting to 1) from team_details
List<TeamDetails> lstOldTeamDetails =
teamDetails.GetEmptyTeamByCountryID(lstUsersDetails[0].CountryID.ToString());
if (lstOldTeamDetails.Count > 0) // Team found start updating process...
{
// Updating old team with the new team details
teamDetails.UpdateNewTeamDetailsByTeamID(lstSiteSetting[0].TeamID.ToString(),
usersDetails.RegionID.ToString(),
lstOldTeamDetails[0].RecordID.ToString());
// Updating users tables with new details.
usersDetails.UpdateNewUserDetails(lstSiteSetting[0].TeamID.ToString(),
lstUsersDetails[0].RecordID.ToString());
// Deleting Expend arena of the old team (if exist)
expendArena.DeleteExpendsByTeamID(lstOldTeamDetails[0].TeamID);
// Deleting old team Arena
teamArena.DeleteArenaByTeamID(lstOldTeamDetails[0].TeamID);
// Build arena for the new team
teamArena.BuiildArenaByTeamID(lstSiteSetting[0].TeamID, lstSiteSetting[0]);
so i have two questions:
A) is my logic looks right?
B) since all of these actions are connected, if one fail (SQL / C# Error) there will be mismatch data inside the database, that's mean i need some kind of Transaction, those is ASP.NET has some kind of built transaction mechanism that can handle these type of situations ?
Thanks.
-
Re: Constructive Criticism
Quote:
Originally Posted by
motil
Ok, so in my data access layer while i'm filling my list of object, let's say i have a column data represent DateTime and i need to check if it as a valid date value, where do i do the calculations ?, should i do it right on the spot (inside the loop) or should i call a method that placed in my business logic layer and do the calculation from there ?
Think about why it would have an invalid date value - you should check the value before it goes into the database. If at some point you're allowing invalid dates to be entered by the user, you should be checking it there. That's the business logic. As for dates coming from the database, you could again check it when your object or list of objects is returned to the business layer. But you shouldn't need to do this - check the values going in rather than the values coming back.
-
Re: Constructive Criticism
Quote:
Originally Posted by
motil
One more question:
Inside my BLL/DAL i can't use the Trace.Warn methods, how do you guys debug what going on in those layers?
Try importing System.Web or use Debug.Write
-
Re: Constructive Criticism
Quote:
Originally Posted by
motil
One More :)
I have this line up of methods calls inside my presentation layer all of those methods are placed inside my BLL, each of of those methods call to other methods that placed inside my DAL which do some kind of database operation, the target of this process is to
delete old team and add new team instead.
Code:
// Getting list of SiteSetting (return 1 item)
List<SiteSetting> lstSiteSetting = siteSetting.GetAllFromSiteSetting();
// Getting list of UsersDetails (return 1 item)
List<UsersDetails> lstUsersDetails = usersDetails.GetAllFromUsersDetailsByRecordID(TeamID);
// Increasing SiteSetting TeamID by 1
siteSetting.IncreaseByOneSiteSettingTeamID();
// Getting list of empty (none user) teams (Limiting to 1) from team_details
List<TeamDetails> lstOldTeamDetails =
teamDetails.GetEmptyTeamByCountryID(lstUsersDetails[0].CountryID.ToString());
if (lstOldTeamDetails.Count > 0) // Team found start updating process...
{
// Updating old team with the new team details
teamDetails.UpdateNewTeamDetailsByTeamID(lstSiteSetting[0].TeamID.ToString(),
usersDetails.RegionID.ToString(),
lstOldTeamDetails[0].RecordID.ToString());
// Updating users tables with new details.
usersDetails.UpdateNewUserDetails(lstSiteSetting[0].TeamID.ToString(),
lstUsersDetails[0].RecordID.ToString());
// Deleting Expend arena of the old team (if exist)
expendArena.DeleteExpendsByTeamID(lstOldTeamDetails[0].TeamID);
// Deleting old team Arena
teamArena.DeleteArenaByTeamID(lstOldTeamDetails[0].TeamID);
// Build arena for the new team
teamArena.BuiildArenaByTeamID(lstSiteSetting[0].TeamID, lstSiteSetting[0]);
so i have two questions:
A) is my logic looks right?
B) since all of these actions are connected, if one fail (SQL / C# Error) there will be mismatch data inside the database, that's mean i need some kind of Transaction, those is ASP.NET has some kind of built transaction mechanism that can handle these type of situations ?
Thanks.
If all of that represents one piece of functionality (update team details, update user details, delete arena, rebuild arena), then move that into one function in your BL layer. Remove the bits where your web controls are involved, and have your BL function accept x number of parameters that it can use to accomplish the same thing. You can even call other BL functions from within that BL function if you need to get some data.
-
Re: Constructive Criticism
Quote:
Originally Posted by
motil
One more question:
Inside my BLL/DAL i can't use the Trace.Warn methods, how do you guys debug what going on in those layers?
9 times out of 10, I add log4net to my web applications, and write out anything that I need to a log file.
Gary
-
Re: Constructive Criticism
Mend, thank you for your suggestions, System.Web didn't helped to bring the Trace method to my DAL, i can't use the Debug method as well...
And I will check that the date is valid before i update the table.
now about the process, moving it to a single method is a good idea and i'll use it but it still not solving the problem that bad sql statement can cause for whatever reason, the only solution i can think of is to use TRANSACTION inside my database and execute all those statements in the same SP, the problem i'm facing now is
A) I'm not sure how to do ROLLBACK with MySql (but i think i can handle this)
B) MySql only support transaction when using innodb tables which is pretty slow as i remember, i hope it got a bit faster since i last used it two years ago.
that's it for now, i let you know how things went :-)
btw, Gary what is log4net ?
-
Re: Constructive Criticism
An easy way to use transactions now:
vb.net Code:
Using myScope As New TransactionScope
'' do your database insert/update stuff here.
End Using
I'm not sure if this is supported by MySql data adapter though. You could give it a try to see yourself.
-
Re: Constructive Criticism
Tried that already, didn't helped me, whatever executed remain the same, no rollback was take place.
Thank you for your help tough.
-
Re: Constructive Criticism
It works for me. I'm using sql server, so it might make difference. But this doesn't seem likely, since almost all databases support transactions and MySql should be no different.
How were you coding it?
-
Re: Constructive Criticism
Hey,
I seem to remember looking into Transactions a while back with the MySql Connector, and when I looked at the source code, it wasn't actually implemented. It could be that newer versions of the connector do include it, but maybe something worth checking. You could post over at the MySql Forum to make sure.
As for log4net:
http://logging.apache.org/log4net/index.html
It's a logging engine, and a very good one. Once it is set up, you simply call:
Code:
log.Debug("Your message here")
And it will log out to a text file. Or, if you want, you can log to the Event Log, an email address, lots of options there.
Gary
-
Re: Constructive Criticism
Quote:
Originally Posted by
motil
Tried that already, didn't helped me, whatever executed remain the same, no rollback was take place.
Thank you for your help tough.
You need to call myScope.Complete() just before the End Using. That commits it. If you don't call it, it will rollback.
using(TransactionScope scope = new TransactionScope())
{
//blah blah
//blah blah blah blah
scope.Complete();
}
-
Re: Constructive Criticism
Quote:
Originally Posted by
motil
Mend, thank you for your suggestions, System.Web didn't helped to bring the Trace method to my DAL, i can't use the Debug method as well...
And I will check that the date is valid before i update the table.
now about the process, moving it to a single method is a good idea and i'll use it but it still not solving the problem that bad sql statement can cause for whatever reason, the only solution i can think of is to use TRANSACTION inside my database and execute all those statements in the same SP, the problem i'm facing now is
A) I'm not sure how to do ROLLBACK with MySql (but i think i can handle this)
B) MySql only support transaction when using innodb tables which is pretty slow as i remember, i hope it got a bit faster since i last used it two years ago.
that's it for now, i let you know how things went :-)
btw, Gary what is log4net ?
If those class names don't work, try typing them into the code. Then click on it, press Ctrl+. (Control dot), it should give you a context menu telling you what to import.