StructureMap and items cached by HttpContext when unit testing - asp.net-mvc

We are using StructureMap to cache a a class by InstanceScope.HttpContext. When unit testing a controller that depends on this type, null reference exceptions are thrown from within StructureMap that seem to indicate that it is trying to access the static current HttpContext (and not the MVC wrappers).
How could we fully configure HttpContext.Current (having decompliled structuremap it seems the error comes from here) to have a valid context that would work correctly with structuremap?

This is a known bug
Just implement the fix and compile.

Have you tried / You could use:
containter.For<ICupCakeService>().HybridHttpOrThreadLocalScoped().Use<MyCupCakeService>();
... Which will use HttpContext storage if it exists, otherwise use ThreadLocal storage.
More: StructureMap - Scoping and Lifecycle Management

Related

Autofac: What is the difference between InstancePerRequest and InstancePerLifetimeScope in an MVC app

I am trying to understand lifetime scopes in Autofac IOC and have the following question.
Assume we have class:
public class TestMemLeak
{
SomeDisposableContext cn;
public TestMemLeak(SomeDisposableContext context)
{
cn = context;
}
}
where the injected dependency SomeDisposableContext implements IDisposable.
In an MVC application I get a memory leak when resolving TestMemLeak object if SomeDisposableContext is registered as InstancePerDependency (default option). The leak is gone if I register it as InstancePerRequest or InstancePerLifetimeScope.
I don't understand why InstancePerLifetimeScope fixes the leak. My understanding is that if we resolve dependency from root then InstancePerLifetimeScope should behave in same way as InstancePerDependency, and the solution to problem would be to pass ILifetimeScope to TestMemLeak class and resolve the dependency using lifetime scope. Why is this assumption wrong and what is the difference between InstancePerRequest and InstancePerLifetimeScope in MVC app scenario (apart from InstancePerRequest looks for specific 'httpRequest' lifetime scope)? When should I use InstancePerRequest? It would be great if someone could explain this especially from memory leaks perspective.
As described in the documentation, InstancePerLifetimeScope works for nested resolves. So it means that in your case one object was instantiated for your HTTP request and it gets its dependencies injected and they are all resolved within the same scope. This is basically done by Autofac MVC integration, it is known as BeginLifetimeScope with the HTTP scope tag.
In case your dependency will be instantiated somewhere else, not within the nested resolution three, it will be outside of the lifetime scope and will not be disposed.
InstancePerRequest however is nothing more than the InstancePerMatchingLifetimeScope with predefined tag constant MatchingScopeLifetimeTags.RequestLifetimeScopeTag. Therefore, your dependency does not need to be instantiated inside the nested lifetime scope resolution, it will be enough for the scope with this tag to be open to get the instance attached to this scope.

Access to Application Context from Grails Filter Constructor

How can I access the Application Context from a Grails Filter. I am able to do so from a Controller by using the following:
def ctx = ApplicationHolder.application.mainContext
But in a Filter ctx is null.
In this case, I'm specifically trying to access the application context in the Filter's constructor.
You shouldn't use the holder classes - they're deprecated in 2.0 and will be removed in a future release.
The best way to access the application context from a controller, filter, service, etc. is to add a dependency injection for the GrailsApplication, i.e
def grailsApplication
Then you can get the context via
def ctx = grailsApplication.mainContext
It's unusual to do work in a constructor that's related to Spring beans, so if possible you should refactor. Grails artifacts are Spring beans, so they're instantiated while the application context is being constructed.
Controllers are a bit different since they're not singletons like most beans, so by the time they get constructed (one per request) the holders are populated. But in general you should avoid doing GORM work, accessing the application context, etc. in a constructor since it's unlikely that things are wired up yet.

Injecting HttpContext in Ninject 2

In my asp.net mvc application I'm using Ninject as a DI framework.
My HttpAccountService is used by my controllers to get info from and to cookies.
For this I need the HttpContext.Current in the HttpAccountService.
As this is a dependency I injected it throught the constructor as such:
kernel.Bind<IAccountService>()
.To<HttpAccountService>()
.InRequestScope()
.WithConstructorArgument("context", HttpContext.Current);
Sadly this always binds to the same context which makes that after the first request finishes this context becomes outdated.
How should I correctly inject my HttpContext?
WithConstructorArgument has an overload that takes a Func<NinjectContext,T>, i.e., you can use:
... .WithConstructorArgument("context",ninjectContext=>HttpContext.Current);
which will call the provided 'callback' lambda within the request processing and obtain the correct value at that point in time [as opposed to you calling the other overload and supplying a constant value which gets computed at Bind<> time].
(If you're not trying to Mock the context, I assume you'll consider using it inline)

Construtor/Setter Injection using IoC in HttpHandler, is it possible?

I've ran into a rather hairy problem. There is probably a simple solution to this but I can't find it!
I have a custom HttpHandler that I want to process a request, log certain info then enter the details in the database. I'm using NUnit and Castle Windsor.
So I have two interfaces; one for logging the other for data entry, which are constructor injected. I quickly found out that there is no way to call the constructor as the default parameterless constructor is always called instead.
So I thought I would use Setter injection and let Castle windsor sort it out. This actually works as when I use container.Resolve<CustomHttpHandler>(); I can check that the logger is not null. (In Application_Start in Global.asax.cs)
The problem is although Castle Windsor can create the instance the http application is not using it??? I think??
Basically the whole reason for doing it this way was to be able to test the logger and data repository code in isolation via mocking and unit testing.
Any ideas how I can go about solving this problem?
Thanks!
Not possible, at least not directly. IHttpHandler objects are instantiated by the ASP.NET runtime and it doesn't allow Windsor to get involved in its creation. You can either:
Pull dependencies, by using the container as a service locator.
Set up a base handler that creates, injects and delegates to your own handlers (see how Spring does it)
Use the container as a service locator for another service that handles the entire request (as saret explained)
What you could do is have the HttpHandler call out to another object that actually handles the request. so in your HttpHandler's ProcessRequest method you would do something like this:
public void ProcessRequest(HttpContext context)
{
var myHandlerObject = container.Resolve<HandlerObject>();
myHandlerObject.ProcessRequest(context or some state/info that is required)
}

Structuremap configuration: One object, multiple interfaces

I have this object "mySessionObject" of type "SessionObject". It implements the interfaces IMessageHandler<MessageA> and IMessageHandler<MessageB>. I should only have one of these objects, and it should live thru the entire HttpSession.
How do I register it with structuremap so that I at any time in the lifetime of the HttpSession can get it by calling ObjectFactory.GetInstance<IMessageHandler<MessageA>>(), or ObjectFactory.GetInstance<IMessageHandler<MessageB>>() ?
Inside of your normal StructureMap configuration, I would add this code:
ObjectFactory.Initialize(x =>
{
x.ForRequestedType<IMessageHandler<MessageA>>().
TheDefaultIsConcreteType<MyImplementingClass>().
CacheBy(InstanceScope.HttpSession);
x.ForRequestedType<IMessageHandler<MessageB>>().
TheDefaultIsConcreteType<MyImplementingClass>>().
CacheBy(InstanceScope.HttpSession);});
}
Note that you will need the 2.5.3 StructureMap release as detailed in this SO thread: StructureMap CacheBy InstanceScope.HttpSession not working
I'm away from a compiler at the moment, but I believe that CacheBy is smart enough to share objects between implementing classes. If not, you can construct a MyImplementingClass another way, and then use TheDefaultIs() rather than TheDefaultIsConcreteType().

Resources