I am using Structuremap as my Dependency Resolver. I am trying to implement Container Per Request Pattern on my Global.asax.cs file.
public IContainer Container
{
get
{
return (IContainer)HttpContext.Current.Items["_Container"];
}
set
{
HttpContext.Current.Items["_Container"] = value;
}
}
public void Application_BeginRequest()
{
Container = ObjectFactory.Container.GetNestedContainer();
}
As the ObjectFactory will not be supported in the future versions of Structuremap I would like get access to the container from the DependencyResolver. How is possible?
Thanks in Advance.
Noufal
Having ran into this question myself, this was the best guide I could find for registering StructureMap with ASP.NET MVC's Dependency Resolver (via the CommonServiceLocator package).
I've copied and pasted the aforementioned article's solution, but I would recommend going through the benefits of this solution in the original article.
public class StructureMapDependencyResolver : ServiceLocatorImplBase
{
private const string StructuremapNestedContainerKey = "Structuremap.Nested.Container";
public IContainer Container { get; set; }
private HttpContextBase HttpContext
{
get
{
var ctx = Container.TryGetInstance<HttpContextBase>();
return ctx ?? new HttpContextWrapper(System.Web.HttpContext.Current);
}
}
public IContainer CurrentNestedContainer
{
get { return (IContainer)HttpContext.Items[StructuremapNestedContainerKey]; }
set { HttpContext.Items[StructuremapNestedContainerKey] = value; }
}
public StructureMapDependencyResolver(IContainer container)
{
Container = container;
}
protected override IEnumerable<object> DoGetAllInstances(Type serviceType)
{
return (CurrentNestedContainer ?? Container).GetAllInstances(serviceType).Cast<object>();
}
protected override object DoGetInstance(Type serviceType, string key)
{
var container = (CurrentNestedContainer ?? Container);
if (string.IsNullOrEmpty(key))
{
return serviceType.IsAbstract || serviceType.IsInterface
? container.TryGetInstance(serviceType)
: container.GetInstance(serviceType);
}
return container.GetInstance(serviceType, key);
}
public void Dispose()
{
if (CurrentNestedContainer != null)
{
CurrentNestedContainer.Dispose();
}
Container.Dispose();
}
public IEnumerable<object> GetServices(Type serviceType)
{
return DoGetAllInstances(serviceType);
}
public void DisposeNestedContainer()
{
if (CurrentNestedContainer != null)
CurrentNestedContainer.Dispose();
}
public void CreateNestedContainer()
{
if (CurrentNestedContainer != null) return;
CurrentNestedContainer = Container.GetNestedContainer();
}
}
You can then set the resolver like so:
public class MvcApplication : System.Web.HttpApplication
{
public static StructureMapDependencyResolver StructureMapResolver { get; set; }
protected void Application_Start()
{
...
// Setup your Container before
var container = IoC.Initialize();
StructureMapResolver = new StructureMapDependencyResolver(container);
DependencyResolver.SetResolver(StructureMapResolver);
}
protected void Application_BeginRequest(object sender, EventArgs e)
{
StructureMapResolver.CreateNestedContainer();
}
protected void Application_EndRequest(object sender, EventArgs e)
{
StructureMapResolver.DisposeNestedContainer();
}
}
The great result of this type of configuration is you receive a new child container per request, with the container being disposed of at the end of each request.
I just tried this and its working, please let me if it is not the best way.
StructuremapMvc.StructureMapDependencyScope.Container
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With