Reputation: 4533
I have a requirement of compose the log message through the path taken by a code in a user click. Let me give an example:
Imagine the classical example: A user clicks in a button in a View, that calls code from the Business Layer that call code from Data Access Layer, that returns data to the Business, that return to a View. I want to compose my log message through these layers. The caller method (in a View) that started the whole process will receive the full message. Here are some code sample just to help me explain what i am trying to achieve.
public void ViewMethod()
{
try
{
BusinessMethod();
}
catch (Exception ex)
{
Logger.Enqueue("exception occurred");
Logger.Print();
}
}
public void BusinessMethod()
{
try
{
DataAccessMethod();
}
catch (Exception ex)
{
Logger.Enqueue("Exception occurred in the business method")
}
}
public void DataAccessMethod()
{
try
{
// some code that executes an SQL command
// Log the SQL Command 1
// Log the SQL Command 2 and do on...
}
catch (Exception ex)
{
Logger.Enqueue("Error occurred, SQL executed is ...", sqlExecuted);
}
}
EDIT: The reason I need this is that I need to log all the SQL's executed in the whole process. If an error occurs in any point of the whole process, the user cant be warned, I need to store as much as possible information because the support technician will need it later.
My question is if there is any design pattern to develop it or passing a Logger reference across the "layers" are acceptable?
Upvotes: 1
Views: 108
Reputation: 19386
I would do something like this
public class Context
{
[ThreadStatic]
private static LogStore _store;
public static Log(....)
{
.....
}
}
public void ViewMethod()
{
var response = BusinessMethod();
if (response.Status = ResponseStatus.Success)
// do something with response.Data
else
// show message?
}
public BusinessMethodResponse BusinessMethod()
{
var response = new BusinessMethodResponse() {Status = ResponseStatus.Failure};
SomeData data;
try
{
data = DataAccessMethod();
}
catch (Exception ex)
{
Context.Log(....);
response.Message = "Data retrieval failed";
return response;
}
try
{
// massage the data here
response.Status = ResponseStatus.Success;
response.Data = myMassagedData;
}
catch (Exception ex)
{
Context.Log(....);
response.Message = "Something failed";
}
return response;
}
public void DataAccessMethod()
{
// some code that executes an SQL command
}
What this do? Now you can call your business objects from MVC, WPF, WinForms, Web Forms, etc...
Upvotes: 1