Am I starting down a C# bad practice path, creating individual classes for an activity log?
I have a web app that contains an activity log for actions the users take. There are multiple types of activities that can be logged.
Here's an example:
public static class NewAccountActivity() {
public static Write(string username) {
//... do stuff to enter a new account activity into the database ...
}
}
public static class NewPostActivity() {
public static Write(string username, long postId, string postTitle) {
//... do stuff to enter a new post activity entry into the database ...
}
}
And then go on to create a new class for every single type of activity to log. Each activity has a .Write() method, with a unique signature for each one (as shown in the code example 开发者_高级运维above)
And then in my web app (asp.net mvc based) I use them like this:
public ActionResult NewAccount(Account account) {
if (Model.IsValid(account)) {
//... do new account stuff ...
NewAccountActivity.Write(account.UserName);
//... redirect to action, or show view ...
}
}
public ActionResult NewPost(Post post) {
if (Model.IsValid(post)) {
//... do new post stuff ...
NewPostActivity.Write(post.UserName, post.postId, post.Title);
//... redirect to action, or show view ...
}
}
Is this a bad idea? Is there a better way? Should these be a bunch of methods jammed into one class?
I started doing this because of an answer to a different question I had on SO.
This is my suggestion.
First of all, no static class should represent an activity. The Logger class can be static, or accessible through a DI container.
Create an interface for an activity, namely IActivity
that has a single Write
or Log
method. For each activity where the processing is bigger than a single line of code, create a class that implements the IActivity
interface.
Now for all other simple activity log, create a default activity that accept a function lambda.
Example, in this code, I assume that each activity builds a string and return it through the Log
function:
public class NewAccountActivity : IActivity
{
private string userName;
public NewAccountActivity(string userName)
{
this.userName = userName;
}
public string Log()
{
return this.UserName;
}
}
public class ActivityEntry : IActivity
{
private Func<string> action;
public ActivityEntry(Func<string> action)
{
this.action = action;
}
public string Log()
{
return this.action();
}
}
Now in your static Logger class, create two functions:
public static class Logger
{
public static void Write(IActivity activity)
{
// Ask activity for its data and write it down to a log file
WriteToFile(activity.Log());
}
public static void Write(Func<string> action)
{
Write(new ActivityEntry(action));
}
}
Then in your code, call your logger class like this:
Logger.Write(new NewAccountActivity(currentUserName));
or if you need to log something else that is simple:
Logger.Write(() => "Hello world");
This last call will create a new instance of ActivityEntry that will log "Hello World".
How about a logger class that takes an enum as an argument so that it knows what type of "activity" it is logging and how to deal with it?
精彩评论