StructureMap and HTTP request-scoped services - wh

2019-07-18 19:29发布

I have an ASP.NET MVC application using StructureMap.

I have created a service called SecurityContext which has a static Current property. A simplified version looks like this:

public class SecurityContext : ISecurityContext
{
    public bool MyProperty { get; private set; }

    public static SecurityContext Current
    {
        get
        {
            return new SecurityContext() { MyProperty = true };
        }
    }
}

I've hooked this up in my StructureMap registry as follows:

For<ISecurityContext>().Use(() => SecurityContext.Current);

My understanding of this Linq expression overload of the Use method is that the returned concrete object is the same for the entire HTTP request scope.

However, I've set up a test case where my context interface is injected in two places, once in the controller's constructor and again using the SetterProperty attribute in the base class my view inherits from.

When debugging I observe the Current static method being hit twice so clearly my assumptions are wrong. Can anyone correct what I'm doing here? The reason I want this request-scoped is because I'm loading certain data into my context class from the database so I don't want this to happen multiple times for a given page load.

Thanks in advance.

1条回答
一夜七次
2楼-- · 2019-07-18 19:45

The default lifecycle for a configuration is Transient, thus each request for an ISecurityContext will create a new instance of SecurityContext. What I think you want is to use the legacy HttpContext lifecycle.

Include the StructureMap.Web nuget package. Then change your configuration to the following:

For<ISecurityContext>()
    .Use(() => SecurityContext.Current)
    .LifeCycleIs<HttpContextLifecycle>();

More information on lifecyles can be found here.

The HttpContextLifecycle is obsolete, however I do not know if or when it will be removed. The StructureMap team does recommend against using this older ASP.Net lifecycle. They state in the documentation that most modern web frameworks use a nested container per request to accomplish the same scoping. Information about nested containers can be found here.

I don't know if the version of ASP.Net MVC you are using is considered a modern web framework. I doubt it is because ASP.Net Core 1.0 is the really the first in the ASP.Net line to fully embrace the use of DI. However, I will defer to @jeremydmiller on this one.

查看更多
登录 后发表回答