This question is more to confirm my diagnosis of an issue we encountered--or to find alternative explanations.
We have an HTTPModule which intercepts every request made to our webforms application. It's job is to translate specific querystring parameters which our integration partners send.
More importantly, it was wired to StructureMap like this:
public class SomeModule : IHttpModule
{
public SomeModule()
{
ObjectFactory.BuildUp(this);
}
public IDependency Dependency开发者_JAVA百科 { get; set; }
}
During a previous release it appeared that the module wasn't being injected by the time it executed it's request-processing. That led to some (ugly) defensive check being added like:
public class SomeModule : IHttpModule
{
public SomeModule()
{
ObjectFactory.BuildUp(this);
if (SomeDependency == null)
{
// HACK: Not sure why this corrects the issue!
Dependency = ObjectFactory.GetInstance<ISomeDependency>();
}
}
public IDependency Dependency { get; set; }
}
You'll notice the HACK comment -- it resolved the issue but without good reason.
Well, this same module has been re-purposed on another site--and the previous hack no longer worked. After looking at it for some time I made the change to move the StructureMap call outside the constructor, and lo-and-behold, it works.
public class SomeModule : IHttpModule
{
public IDependency Dependency { get; set; }
public void IHttpModule.Init(HttpApplication context)
{
Initialize();
// the rest of the code
}
private bool _initialized;
private void Initialize()
{
if (_initialized)
{
return;
}
ObjectFactory.BuildUp(this);
_initialized = true;
}
}
So, my I have a few questions around this behavior:
- My suspicion is that StructureMap was not fully initialized/configured when the HttpModule constructor was being called -- agree/disagree, any insight?
- I haven't found any reference materials that state when to expect StructureMap to be initialized and ready to service requests. Is there any such documentation?
I wouldn't expect the behavior to be very predictable when you're trying to build up a type in its constructor. Many actions that are normally considered safe are not considered safe in a constructor (like using a virtual property in a class).
Where you moved the code to looks much better and I would leave it there. If you can't have the container create the instance itself (and therefore are forced to build it up) some sort of Initialize method is the preferred place to do the build up action.
To answer the question you have at the end of your post: It is up to the developer to determine when StructureMap is initialized. In a web application, this is almost always done in the Global.asax in Application_Start(). In that case, I would expect the container to be ready when your module is called.
精彩评论