is StructureMap HttpContextScoped necessary?
Asked Answered
P

1

8

I saw a code as below in a tutorial of EF code first , MVC and StructureMap to create a Context Per Request pattern:

    protected void Application_Start()
    {
        ...

        initStructureMap();

    }

    private static void initStructureMap()
    {

        ObjectFactory.Initialize(x =>
        {
            x.For<IUnitOfWork>().HttpContextScoped().Use(() => new Context());
            x.For<IFirstEntity>().Use<FirstEntity>();
            x.For<ISecondEntity>().Use<SecondEntity>();
            x.For<IThirdEntity>().Use<ThirdEntity>();
        });

        ControllerBuilder.Current.SetControllerFactory(new StructureMapControllerFactory());
    }

    protected void Application_EndRequest(object sender, EventArgs e)
    {
        ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects();
    }


public class StructureMapControllerFactory : DefaultControllerFactory
{
    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
    {
        return ObjectFactory.GetInstance(controllerType) as Controller;
    }
}

FirstEntity ,SecondEntity and ... all need IunitOfWork in their constructor .

as you can see it just uses HttpContextScoped() for the Context not others and in the EndRequest event it calls ReleaseAndDisposeAllHttpScopedObjects() .

1- is this a correct approach ?

2- shall I use HttpContextScoped() for all other Service layer Interfaces or not just for IUnitOfWork? e.g

x.For<IFirstEntity>().Use<FirstEntity>();

or

x.For<IFirstEntity>().HttpContextScoped().Use(() => new FirstEntity());

3- ReleaseAndDisposeAllHttpScopedObjects() disposes all instances or just disposes Context ?

Palmary answered 10/12, 2012 at 9:41 Comment(0)
K
8

The convention for web applications is that you keep the same ORM context/UnitOfWork during the entire http request. This is in order to work with the same entities during the request, keep the data consistent and minimize the database calls made. The HttpContextScoped life cycle ensures that the same UoW instance is used during a request for all instances having a dependency on it.

So 1) yes, it's correct

Regarding the rest of the "service layer interfaces", it depends on whether it needs to be the same instance during the entire request. Ask yourself: "will the state of this object be needed during the entire request"? For most "services" this is not the case. Also note that making something "HttpContextScoped" will also make all it's dependencies stay during that scope.

This leads me to say 2) In most cases, no

ReleaseAndDisposeAllHttpScopedObjects disposes all objects in the container registered with HttpContextScoped. By default objects are scoped as transient (new instance per call) in Structuremap.

So 3) Just the IUnitOfWork instance will be disposed.

Keele answered 10/12, 2012 at 10:15 Comment(4)
Updated answer. Unless you need to keep the same state or the instance is expensive to create and can share the state during the request, go with transient objects.Keele
thank you , my problem is then when these instances will be disposed ? do they dispose in EndRequest too or not ?Palmary
The transient instances will not be disposed unless you dispose them manually, or stick them in a nested container. If you need to control the lifetime of injected dependencies, you might want to go with a factory approach. An alternative is to change your implementation so that you don't inject disposables, but something that wraps them and controls their lifetime.Keele
actually I'm facing a high memory usage issue in my app , looking for the reason I'm checking structureMap configs .Palmary

© 2022 - 2024 — McMap. All rights reserved.