I continuously find myself having to write timed windows services that poll outside queues or run timed processes. I consequently have a fairly robust template by which to do this, but I find that every time I write a service to do this, I start with the same template and then write the process inside it.
This morning I find myself wondering if I could actually turn this template into a framework that I could inject my process into. My basic template is only 122 lines of code. Due to differing requirements for each process - i.e. different number of arguments, different argument types and different dependencies (some are dependent on Web Services, some on databases etc.) I can't figure out how to set up my basic template to receive an injected process.
The heart of the template is just a timer that stops when it initializes and starts the process and then restarts the timer once the process completes. I then add my process method and any dependencies right into the template.
Has anyone got any ideas how to do this? I've looked at dependency injection and often use it already for injection of things like data store connectivity? Is there a way to inject a delegate with an unknown number/type of parameters into a class? Am I looking at this incorrectly?
This is the template I have:
TimedProcess.Template.cs
using System;
using System.Timers;
public partial class TimedProcess : IDisposable
{
private Timer timer;
public bool InProcess { get; protected set; }
public bool Running
{
get
{
if (timer == null)
return false;
return timer.Enabled;
}
}
private void InitTimer(int interval)
{
if (timer == null)
{
timer = new Timer();
timer.Elapsed += TimerElapsed;
}
Interval = interval;
}
public void InitExecuteProcess()
{
timer.Stop();
InProcess = true;
RunProcess();
InProcess = false;
timer.Start();
}
public void TimerElapsed(object sender, ElapsedEventArgs e)
{
InitExecuteProcess();
}
public void Start()
{
if (timer != null && timer.Interval > 0)
timer.Start();
}
public void Start(int interval)
{
InitTimer(interval);
Start();
}
public void Stop()
{
timer.Stop();
}
public TimedProcess()
: this(0)
{
}
public TimedProcess(int interval)
{
if (interval > 0)
InitTimer(interval);
}
private disposed = false;
public Dispose(bool disposing)
{
if (disposed || !disposing)
return;
timer.Dispose();
disposed = true;
}
public Dispose()
{
Dispose(true);
}
~TimedProcess()
{
Dispose(false);
}
}
TimedProcess.cs
using System;
public partial class TimedProcess
{
public void RunProcess()
{
//Hook process to run in here
}
}
So I'm looking to modify it so that my Windows Service spawns a new TimedProcess and injects it with the process that needs running thereby removing the TimedProcess code from my Windows Service entirely and having it reference the DLL.
Edit: Thanks for everyone's help. I realized that if I push my RunProcess() method outside of my TimedProcess library and pass that in as an Action in the constructor, then this simplifies everything the way I was looking to:
[Simplified for brevity]
public class TimedProcess
{
Action RunProcess;
Timer timer = new Timer();
private void TimerElapsed(object sender, ElapsedEventArgs e)
{
if (RunProcess != null)
RunProcess();
}
public TimedProcess(Action action, int interval)
{
timer.Interval = interval;
RunProcess = action;
timer.Start();
}
}
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…