Dependency Injection in NUnit

140 views
Skip to first unread message

Rob Prouse

unread,
Nov 6, 2014, 8:30:30 PM11/6/14
to nunit-d...@googlegroups.com
There have been a few instances recently that made me think that we should have an internal dependency injection framework with NUnit, but working on Portable has really driven home the point. It would be very nice to be able to inject platform specific implementations of interfaces into the framework from the platform specific runners.

I am thinking a NInject configuration in code type syntax. Something like

Bind<ILogger>().To<FileLogger>();

To keep it simple, we don't need to do full constructor injection. We could just do something like the following in code.

var log = Kernel.Get<ILogger>();

We could add simple scope semantics to allow for new object per call, per thread or as a singleton.

Some of the places that it would be useful are,

- Logging/Error output - From certain places in the code, it is very hard to surface errors that are seen by the user. We currently have an InternalTraceWriter, but it would be nice to have some sort of ILogger injected in from the runner. We could inject multiple loggers to log to a file, output to the console, etc.

- PlatformAttribute - In the portable framework, much of the information we need isn't available. It would be nice to inject classes that could provide that information.

- Runners - We are now down to one runner, but we have talked about a v2 runner. It would be nice to be able to inject runners, we could iterate through available runners to determine which support a given test assembly and run tests in the appropriate runner.

I am sure there are more opportunities. I don't think it would be hard to write a limited dependency injection framework that satisfies just our needs and would be willing to take on the task.

I am not sure how this would work with our attempt to separate the runners from the framework via the engine, but I think it is worth exploring.

What do you think? Has anyone else been thinking along these lines? If so, how did you think we would tackle it?

 Is it a useful idea? Should I enter an issue?

Rob

Charlie Poole

unread,
Nov 7, 2014, 4:37:06 PM11/7/14
to nunit-developer
In general, I think it's a pretty good idea. That said, I'd be fairly
well tempted to consign the issue to 'Future' because we have such a
lot of work to complete for a 3.0 release as it is. I've already
pushed the expected Beta date to the end of the year and even that may
be optimistic. I'd feel more positive about this as an immediate task
if there were some existing blocking issues it resolved.

On specific points:

* Remember that InternalTraceWriter is designed as completely adhoc so
that it won't interfere with any logging or tracing used by the user.
It's for us, not really for users.
* We decided to eliminate capture of external (user) loggers and
tracing because we felt it wasn't the job of our framework.
* Platform attribute is definitely an issue.
* Not sure what you mean by the phrase "v2 runner" - is it the planned
driver for v2? That's not in the framework (which is what I thought
you were talking about here) but the engine. I planned it as a plugin
and was going to use mono.addins. Of course, that plan dates back many
years and I want to look at what has come along since then. However,
AFAIK, DI frameworks don't generally do everything mono-addins does.
I'm hoping to get very soon to a point where I can work on that.

As I was writing this I realized that I wasn't sure what layer you
meant it to apply to. Framework, Engine or Runner(s)?

Charlie
> --
> You received this message because you are subscribed to the Google Groups
> "NUnit Developer List" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to nunit-develop...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Charlie Poole

unread,
Nov 7, 2014, 4:38:45 PM11/7/14
to nunit-developer
A further thought: If we used (say) NInject at the framework level and
the user was using it too, what would be the consequence?

It's possible conflicts like this that have made me want to stay away
from any 3rd party software the user might also want to use at the
framework level.

Charlie

Rob Prouse

unread,
Nov 7, 2014, 5:05:23 PM11/7/14
to nunit-d...@googlegroups.com
I am fine leaving it to future, I just wanted to get the idea out there.

As to where it would be used, ideally, I would like the runner layer to setup the injection which would be consumed by the other layers. I'm not sure how we do that and maintain dependency separation between the layers though.

Something like NInject would be perfect, but I think you are right about potential conflicts. That is why log4net was removed, wasn't it? I was thinking of a lighter weight framework written by us, or possibly pulled into our code and put in a new namespace so it won't conflict. mono.addins might give us much of what we want. I am not familiar with it, but it might be a good place to start.
--

Rob Prouse

 

I welcome VSRE emails. Learn more at http://vsre.info/

Charlie Poole

unread,
Nov 7, 2014, 5:29:31 PM11/7/14
to nunit-developer
OK. That works for me. Why don't you file an issue and assign it to 'Future'?
Reply all
Reply to author
Forward
0 new messages