Is this 4-tier architecture good?(Exception handling is important for me :)
I have this layers in my application:
- Entities
- Database (with Entities reference)
- Business (with database and Entities references)
- User Interface (with Business and Entities references)
Here is an example of my codes:
- UserDAL class in database layer:
public class UsersDal
{
databaseDataContext db;
public UsersDal()
{
try
{
db = new databaseDataContext(ConnectToDatabase.GetConnectionString());
}
catch (Exception ex)
{
throw ex;
}
}
public List&l开发者_如何学运维t;User> GetAllUsers()
{
try
{
return (from u in db.Users select u).ToList();
}
catch (Exception ex)
{
throw ex;
}
}
And so on...
In the UserBLL class in Business layer i write like this:
public class UsersBll
{
UsersDal user;
public UsersBll()
{
try
{
user = new UsersDal();
}
catch(Exception ex)
{
throw new ProjectException(Errors.CannotCreateObject, ex);
}
}
public List<User> GetAllUsers()
{
try
{
return user.GetAllUsers();
}
catch(Exception ex)
{
throw new ProjectException(Errors.CannotReadData, ex);
}
}
And in UI i write:
private void GetUsers()
{
try
{
UsersBll u = new UsersBll();
datagrid.DataSource = u.GetAllUsers();
}
catch(ProjectException ex)
{
MessageBox(ex.UserMessage);// and also can show ex.InnerException.Message for more info
}
}
Well, I use a ProjectException named class to produce an error contain a BLL created message by me and an Exception message that the OS automatically manipulate. Also i create an enum of possible errors and a dictionary here is some details about it:
namespace Entities
{
public enum Errors
{
CannotCreateObject,
CannotReadData,
CannotAdd,
CannotEdit,
CannotDelete,...
}
[global::System.Serializable]
public class ProjectException : Exception
{
public ProjectException(Errors er, Exception ex)
: base(errors[er], ex)
{
currentEx = er;//er is Errors enum
}
static ProjectException()
{
errors = new Dictionary<Errors, string>();
errors.Add(Errors.CannotCreateObject, "the application cannot connect to database!");
errors.Add(Errors.CannotReadData, "the application cannot read data from database"); //...
}
public string UserMessage
{
get
{
try
{
return errors[currentEx];
}
catch
{
return "Unknown error!";
}
}
}
Is this good? it work for me fine. what's your idea?
It is almost always wrong within a catch (ex)
to do a throw ex;
. Either just do throw;
or else throw new whateverException("someMessage", ex);
. The decision of whether to use the former form or the latter generally depends upon whether you are crossing an application layer. If an AcmeServerDatabaseWrapper, which derives from DatabaseWrapper type, is performing a query when an AcmeDatabaseTableNotFoundException is thrown, it should catch that and rethrow it as a DatabaseWrapperTableNotFoundException (if such a type exists) or as a DatabaseWrapperOperationFailedException. Client code which has an object derived from DatabaseWrapper should be able to know what types of exceptions that object will throw, without having to know what type of object it is. Any exception which escapes from the database layer without being wrapped is an exception the client code is unlikely to be able to handle sensibly, but might handle erroneously (thinking it occurred in a context other than where it actually happened).
精彩评论