0

I am a bit new to StructureMap's IoC (and IoC in general). From examples, I have my stuff set up like this:

DefaultRegistry:

public DefaultRegistry() {
        Scan(
            scan => {
                scan.TheCallingAssembly();
                scan.WithDefaultConventions();
                scan.With(new ControllerConvention());
            });
        For<IRepository>().Use<Repository>().Ctor<string>("connectionString").Is(ConfigurationManager.ConnectionStrings["DBConnection"].ConnectionString);
        //For<IExample>().Use<Example>();
    }

Then, in each controller that any Action needs the database, I have:

private IRepository _Repository;

    public TipsController(IRepository repository)
    {
        _Repository = repository;
    }

When I need to use it, I just do:

data.Information = await _Repository.GetInformationAsync();

When I used ADO.NET, I always had a using statement around everything. I've seen examples of Entity Framework that utilizes the using statement. But, when using EF in conjunction with StuctureMap, do I need to somehow wrap a using statement around it? If so, how do I?

ScubaSteve
  • 7,724
  • 8
  • 52
  • 65

1 Answers1

1

If you create a context and use it within the scope of a single method then it's always recommended that you wrap your DbContext use within a using statement as you mentioned, however when your DbContext life time is not bound to the execution of a single method then you have to dispose of the context youself.

A common pattern (and the one recommended in the StructureMap 3 documentation) is to have harness nested containers that are bound to the HttpContext.

This works by creating a nested container at the beginning of a user's Http request and then disposing of the nested container (and the DbContext instance) at the end of the request.

When using an ORM such as Entity Framework with an IoC Container like StructureMap, you can use this nested container that's bound to the HTTP request to control the lifetime of your DbContext. So as a request begins, a new database connection is created and then close and disposed at the end of the request.

This is probably the most complete tutorial that I've found that best describes setting up nested StructureMap containers that are bound to the Http request, and is almost identical to the way the StructureMap.MVC5 package does it that's referenced in the documentation.

Once this is implemented all you would need to do pull the open database connection from the container and dispose of it at the end of the Http request within application_endrequest in your Global.asax.cs file

Joseph Woodward
  • 9,191
  • 5
  • 44
  • 63
  • It's nice that this guy has his take on it, but how is there not an official "how-to" with this? I'd think it would be a very common issue. – ScubaSteve Feb 20 '15 at 00:15
  • This is the method that the StructureMap documentation recommends - http://structuremap.github.io/the-container/nested-containers/. In fact, if you look under the "Who uses it?" heading you'll see there's a recommendation to use the `StructureMap.MVC5` package, which stores the nested container in an identical way to the earlier link. The only reason I referenced that tutorial is it gives a more in-depth example as to how it works. – Joseph Woodward Feb 20 '15 at 00:29
  • Looking at the latest version of StructureMap's code, it looks like this is all done for us already. – ScubaSteve Feb 21 '15 at 21:17
  • If you're talking about the HttpContextScoped() method then yes, this will achieve the same thing and be suitable for disposing of your database connection, however it will not take advantage of StructureMap's nested containers per HTTP request (see link in my comment above for more on nested containers and their advantage), instead it will dispose of the dependency at the end of the request but not anything else within your SM registry. – Joseph Woodward Feb 22 '15 at 01:20
  • I did read over your links and looking through the code that StructureMap v3.1.1.134 creates for you, this is handled as long as you put your mapping code inside DefaultRegistry(). But, maybe I'm missing something. – ScubaSteve Feb 22 '15 at 20:12