ITimer icon indicating copy to clipboard operation
ITimer copied to clipboard

How to set autoreset on the timer instance?

Open basprins opened this issue 2 years ago • 2 comments

Hi, Just came across your library. It find it a bit cumbersome to set certain properties on the timer. e.g autoReset. I need to pass this via the constructor, which is rather annoying when you combine this with e.g. autofac.

In autofac (or any IoC container I guess), I want to register a timer so that any user can get a timer injected.

something like

            builder.RegisterType<SystemTimer>().As<ISignaler>();

Now, any class that requires a timer can have an ISignaler injected. But, now the IoC container is also responsible to define the behavior of the timer. Again, e.g., the autoreset will default to true. Which should be configurable per use of the timer. I can have two classes, where one requires the autoreset to be false, and the other class requires it to be true.

Of course, I can set explicitly define how autofac should instantiate my timer

            builder.RegisterType<SystemTimer>()
                .As<ISignaler>()
                .WithParameter(new Autofac.NamedParameter("autoReset", false));

But this would mean that each class with requires an ISignaler will receive a timer with autoreset disabled.

Of course, I can work around this, but then again I need to boilerplate stuff around the SystemTimer class (e.g. make a factory), which kind of defeats the purpose all together of using this library (then I might as well rely on the .net's System timer instead).

How do you see this? Can you relate? Or have you thought about this too, and can I achieve what I want in a different way?

PS: Best regards from Nuenen ;-)

basprins avatar Feb 15 '23 10:02 basprins

which kind of defeats the purpose all together

The purpose of this library is to make timer related code easily testable by abstracting timer related code to a common interface (ISignaler) and providing built-in timers that wrap common timers (System, Threading and Periodic timers) and a timer implementing the same ISignaler interface for testing purposes; the TestTimer.

  • A factory is probably the way to go if you need multiple timers and want to use DI to provide ready-to-use timers to constructors.
  • You could also make a simple wrapper-class that implement sISignaler; you can see how it's done on any of the provided timers and then extend it with properties or methods or constructors you need to be able to set the interval from within another constructor.
  • Or use the Start(TimeSpan) overload where you can specify an interval when starting the timer.

PS: Best regards from Nuenen ;-)

👋

RobThree avatar Feb 15 '23 22:02 RobThree

for this we create two interfaces ( IAutoTimer, IManualTimer ) and timer wrapper ( AutoTimer, ManualTimer ),

public interface IAutoTimer : ISignaler {}
public class AutoTimer : SystemTimer, IAutoTimer {}

public interface IManualTimer : ISignaler {}
public class ManualTimer : SystemTimer, IManualTimer
{
	public ManualTimer(): base( false ) {}
}

then you can register these two and inject the require type of timer.

Services.AddScoped<IAutoTimer, AutoTimer>();
Services.AddScoped<IManualTimer, ManualTimer>();

@RobThree maybe this would be a great addition to this lib ( simple wrapper on all timer types ) because AutoReset is the only property that cant be changed after creating the timer. This way the DI usage is much easier and the readability is improved ( interface name makes it clear how the timer tick behave without knowing the implementation )

puschie286 avatar Aug 10 '23 13:08 puschie286