Configuration for Object Creation
Recently I've used StructureMap in one of my projects and I begin to like it, especially I can control the object life cycle via StructureMap without changing my code. The followings are some ways how to configure StructureMap to create object instance.
-
Per request basis
StructureMap by default constructs object instance transiently. Thus, each time you will get a new instance.
public void NewPerRequest() { Container mymap = new Container(x => { x.For<ISimple>().Use<Simple>(); }); ISimple first = mymap.GetInstance<ISimple>(); ISimple second = mymap.GetInstance<ISimple>(); string formatter = "PerRequest [default]: instances are the same? {0}"; System.Console.WriteLine(formatter, ReferenceEquals(first, second)); }
-
Singleton
StructureMap can inject code for you to apply Singleton design pattern if you want your object remains one and only one instance to be active during the life of the application.
public void Singleton() { Container mymap = new Container(x => { x.For<ISimple>().Singleton().Use<Simple>(); }); ISimple first = mymap.GetInstance<ISimple>(); ISimple second = mymap.GetInstance<ISimple>(); string formatter = "Singleton: instances are the same? {0}"; System.Console.WriteLine(formatter, ReferenceEquals(first, second)); }
-
HttpContextScoped
You can configure StructureMap to contruct objects to live in HttpContext scope. This method only uses in Web application.
public void HttpContextScoped() { Container mymap = new Container(x => { x.For<ISimple>().HttpContextScoped().Use<Simple>(); }); using (new MockHttpContext()) { ISimple first = mymap.GetInstance<ISimple>(); ISimple second = mymap.GetInstance<ISimple>(); string formatter = "HttpContextScoped: instances are the same: {0}"; System.Console.WriteLine(formatter, ReferenceEquals(first, second)); } }
-
HttpContextLifecycle
Configure StructureMap to contruct objects to live in HttpContext life cycle. This method only uses in Web application.
public void HttpContextLifecycle() { Container mymap = new Container(x => { x.For<ISimple>().LifecycleIs(new HttpContextLifecycle()).Use<Simple>(); }); using (new MockHttpContext()) { ISimple first = mymap.GetInstance<ISimple>(); ISimple second = mymap.GetInstance<ISimple>(); string formatter = "HttpContextLifecycle: instances are the same: {0}"; System.Console.WriteLine(formatter, ReferenceEquals(first, second)); } }
-
HttpSessionLifecycle
Configure StructureMap to instantiate an object in HttpSession context. Like the previous two methods, it only works in regular Web environment.
public void HttpSessionLifecycle() { Container mymap = new Container(x => { x.For<ISimple>().LifecycleIs(new HttpSessionLifecycle()).Use<Simple>(); }); #region Create HttpSession environment for test // Mock a new HttpContext by using SimpleWorkerRequest System.Web.Hosting.SimpleWorkerRequest request = new System.Web.Hosting.SimpleWorkerRequest("/", string.Empty, string.Empty, string.Empty, new System.IO.StringWriter()); System.Web.HttpContext.Current = new System.Web.HttpContext(request); MockHttpSession mySession = new MockHttpSession( Guid.NewGuid().ToString(), new MockSessionObjectList(), new System.Web.HttpStaticObjectsCollection(), 600, true, System.Web.HttpCookieMode.AutoDetect, System.Web.SessionState.SessionStateMode.Custom, false); System.Web.SessionState.SessionStateUtility.AddHttpSessionStateToContext( System.Web.HttpContext.Current, mySession ); #endregion // now we are ready to test ISimple first = mymap.GetInstance<ISimple>(); ISimple second = mymap.GetInstance<ISimple>(); string formatter = "HttpSessionLifecycle: instances are the same: {0}"; System.Console.WriteLine(formatter, ReferenceEquals(first, second)); }
-
HybridSessionLifecycle
Those related to HttpContext or HttpSession are only used in ASP.NET Web environment. You won't be able to have your instance to run in client or service environment. HybridSessionLifecycle may be used to resolve it. For this method, HybridSessionLifecycle will try to use HttpContext storage if it exists; otherwise, it uses ThreadLocal storage. However, I found that this method somehow won't work with HttpHandler.
// According to my experience, // HybridSessionLifecycle works in most situations (including regular Web environment, // Web service, console) but it doesn't work well with HttpHandler while // HybridHttpOrThreadLocalStorage does. public void HybridSessionLifecycle() { Container mymap = new Container(x => { x.For<ISimple>().LifecycleIs(new HybridSessionLifecycle()).Use<Simple>(); }); ISimple first = mymap.GetInstance<ISimple>(); ISimple second = mymap.GetInstance<ISimple>(); string formatter = "HttpSessionLifecycle: instances are the same: {0}"; System.Console.WriteLine(formatter, ReferenceEquals(first, second)); }
-
HybridHttpOrThreadLocalScoped
Like HybridSessionLifecycle, it works for most situations. It also work well in a HttpHandler.
// Unlike HybridSessionLifecycle, it works well with HttpHandlers and WCF Services // besides a regular ASP.NET environment. public void HybridHttpOrThreadLocalScoped() { Container mymap = new Container(x => { x.For<ISimple>().HybridHttpOrThreadLocalScoped().Use<Simple>(); }); ISimple first = mymap.GetInstance<ISimple>(); ISimple second = mymap.GetInstance<ISimple>(); string formatter = "HybridHttpOrThreadLocalScoped: instances are the same: {0}"; System.Console.WriteLine(formatter, ReferenceEquals(first, second)); }
-
UniquePerRequestLifecycle
You can instruct StructureMap to create an unique instance per request in order to ensure no corrupted data and all states in fresh.
public void UniquePerRequestLifecycle() { Container mymap = new Container(x => { x.For<ISimple>().LifecycleIs(new UniquePerRequestLifecycle()).Use<Simple>(); }); ISimple first = mymap.GetInstance<ISimple>(); ISimple second = mymap.GetInstance<ISimple>(); string formatter = "HttpContext Scope: instances are the same: {0}"; System.Console.WriteLine(formatter, ReferenceEquals(first, second)); }