1

A colleague and I were just talking about unit testing when I realised that I write code differently in certain circumstances...

If I'm using Entity Frameworks on its own, I'll tend to use the IDisposable interface via a using block:

using (Context ctx = new Context()) { whatever(); }

But when I'm writing code that will be unit tested, I move the instantiation of the context into a constructor, so that I can pass in mocks to be used instead. I understand that this is a type of dependency injection, specifically "constructor injection".

Taking only a cursory look, I see this latter pattern recommended in a couple of articles:

The problem with this (as my colleague and I reflected) is that the dispose method is never called. I suppose these objects get finalised as they move out of scope, but it seems less than ideal.

So, my question: is there a way to combine dependency injection with use of IDisposable?

I can imagine three possible categories of answer:

  1. "Yes, there is a way and here's how..."
  2. "No, there isn't a way. This is something you'll have to live with."
  3. "Tom, you have completely misunderstood something."

Whichever it is, we'd be really grateful!

Tom Wright
  • 11,278
  • 15
  • 74
  • 148
  • 1
    3. The container will dispose it, when you configure it to. This means you won't have to use `using () { }` anymore in your code. – CodeCaster Jul 10 '17 at 13:27
  • Like CC says, the container will call `Dispose` if your object implements `IDisposable` at the right time depending on how you registered it. – DavidG Jul 10 '17 at 13:28
  • What DI framework are you using? Or are you using constructor chaining and passing in a new `DbContext` instance from the default constructor (ie. you are not using a DI framework). – Igor Jul 10 '17 at 13:31
  • @Igor The latter. We're only using DI to inject mock DB contexts, so we're not using a full-blown DI container. – Tom Wright Jul 10 '17 at 13:34
  • @CodeCaster We're not using a DI container, we're just passing an instance of a mock context to an overload of the default, parameterless constructor. – Tom Wright Jul 10 '17 at 13:35
  • 2
    Related: https://stackoverflow.com/a/30287923/264697 – Steven Jul 10 '17 at 13:44

1 Answers1

2

The latter. We're only using DI to inject mock DB contexts, so we're not using a full-blown DI container.

You are correct, the DbContext instance will never have Dispose called on it (assuming you are not manually calling dispose in one of your methods). I recommend you select a good DI framework (my personal fav. is AutoFac). The framework will handle disposing anything that implements IDisposable, is registered with the framework, and is injected/supplied by the framework.

Igor
  • 60,821
  • 10
  • 100
  • 175