Reputation: 3665
I have an application that will run once every minute. After completing, the app will write to a log table before it exits. This object closely maps that log table:
class SendResult
{
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public TimeSpan ExecutionTime { get
{
return EndTime - StartTime;
}
public bool RequestChecked{ get; set; }
public int RequestID { get; set; }
public bool RequestRequiresFileSend { get; set; }
public bool FilesRead { get; set; }
public bool FilesSent { get; set; }
public SendResult() { }
}
Each property will be updated at a different point in the app. I have achieved this by declaring the object once and making it static:
class Program
{
public static SendResult Result;
public Program()
{
Result = new SendResult();
Result.StartTime = DateTime.Now;
// do stuff...
Result.EndTime = DateTime.Now;
LogUtility.Log(Result);
}
}
..and everywhere throughout the app I just call:
Program.Result.FilesRead = ...
I know an alternative is to construct the app around SendResult, like this:
SendResult result = new SendResult();
result.StartTime = DateTime.Now;
var request = new RequestHandler().CheckRequest();
result.RequestChecked = request.Checked;
result.RequestID = request.RequestID;
result.RequestRequiresFileSend = request.FileSendRequired;
var sendResult = new FileSender(request.ResuestID).Send();
result.FilesRead = sendResult.FilesRead;
// ...and so on
But in a case where you have to insert this result tracking after all your code has been written, is there a better way than the global var method I have used?
Upvotes: 0
Views: 75
Reputation: 30195
Static variables are usually not a good idea, there is almost no uses of them in the modern application with Dependency Injection. It's use adds a state and increase coupling, making it much more complicated to e.g. unit test all your components in isolation.
So the simplest approach would be to just create the required object and send it to all the methods that require editing. It's a bit hard to say generally though, it might be better that all your methods do return their own objects that are later composed into the resulting one that is saved to the database.
But while there can be different strategies to achieve what you want, using static variable is most likely not the best of them.
Upvotes: 1
Reputation: 1555
The parts of the code summarized as "do stuff" should take in the SendResult
instance as a dependency that is either explicitly pushed into them, or possibly resolved in some way other than directly depending on accessing a static field in Program
. You can pass the reference directly using constructor arguments, object properties, or method parameters. Indirect ways to do that could be implemented using an IoC/DI container. The idea is to reduce coupling, which is most of the time a good idea.
Potentially, your application could benefit from using the Pipes and Filters Architectural Pattern, but only if you have scaleability and flexibility requirements. Otherwise, the introduced complexities would be counterproductive for your particular case.
Upvotes: 1