PageRenderTime 59ms CodeModel.GetById 35ms RepoModel.GetById 1ms app.codeStats 0ms

/src/core/OpenRasta.Tests.Unit/DI/when_resolving_instances.cs

https://github.com/grahamrhay/openrasta-stable
C# | 399 lines | 295 code | 77 blank | 27 comment | 1 complexity | 61f08cfa1eb2e91ef6a80a3158787c76 MD5 | raw file
  1. #region License
  2. /* Authors:
  3. * Sebastien Lambla (seb@serialseb.com)
  4. * Copyright:
  5. * (C) 2007-2009 Caffeine IT & naughtyProd Ltd (http://www.caffeine-it.com)
  6. * License:
  7. * This file is distributed under the terms of the MIT License found at the end of this file.
  8. */
  9. #endregion
  10. using System;
  11. using System.Linq;
  12. using NUnit.Framework;
  13. using OpenRasta.DI;
  14. using OpenRasta.Hosting;
  15. using OpenRasta.Hosting.InMemory;
  16. using OpenRasta.Pipeline;
  17. using OpenRasta.Testing;
  18. using OpenRasta.Tests.Unit.DI;
  19. using OpenRasta.Tests.Unit.Fakes;
  20. namespace InternalDependencyResolver_Specification
  21. {
  22. public abstract class when_resolving_instances : dependency_resolver_context
  23. {
  24. public class TypeWithDependencyResolverAsProperty
  25. {
  26. public IDependencyResolver Resolver { get; set; }
  27. }
  28. public class TypeWithPropertyAlreadySet
  29. {
  30. public TypeWithPropertyAlreadySet()
  31. {
  32. Resolver = new InternalDependencyResolver();
  33. }
  34. public IDependencyResolver Resolver { get; set; }
  35. }
  36. [Test]
  37. public void a_property_that_would_cause_a_cyclic_dependency_is_ignored()
  38. {
  39. Resolver.AddDependency<RecursiveProperty>();
  40. Resolver.Resolve<RecursiveProperty>().Property.
  41. ShouldBeNull();
  42. }
  43. [Test]
  44. public void a_type_cannot_be_created_when_its_dependencies_are_not_registered()
  45. {
  46. Resolver.AddDependency<IAnother, Another>();
  47. Executing(() => Resolver.Resolve<IAnother>())
  48. .ShouldThrow<DependencyResolutionException>();
  49. }
  50. [Test]
  51. public void an_empty_enumeration_of_unregistered_types_is_resolved()
  52. {
  53. var simpleList = Resolver.ResolveAll<ISimple>();
  54. simpleList.ShouldNotBeNull();
  55. simpleList.ShouldBeEmpty();
  56. }
  57. [Test]
  58. public void a_type_can_get_a_dependency_resolver_dependency_assigned()
  59. {
  60. Resolver.AddDependencyInstance(typeof (IDependencyResolver), Resolver);
  61. Resolver.AddDependency<TypeWithDependencyResolverAsProperty>(DependencyLifetime.Transient);
  62. Resolver.Resolve<TypeWithDependencyResolverAsProperty>()
  63. .Resolver.ShouldBeTheSameInstanceAs(Resolver);
  64. }
  65. [Test]
  66. public void a_property_for_which_there_is_a_property_already_assigned_is_replaced_with_value_from_container()
  67. {
  68. Resolver.AddDependencyInstance(typeof(IDependencyResolver),Resolver);
  69. Resolver.AddDependency<TypeWithPropertyAlreadySet>(DependencyLifetime.Singleton);
  70. Resolver.Resolve<TypeWithPropertyAlreadySet>()
  71. .Resolver.ShouldBeTheSameInstanceAs(Resolver);
  72. }
  73. }
  74. public abstract class when_registering_for_per_request_lifetime : dependency_resolver_context
  75. {
  76. InMemoryContextStore InMemoryStore;
  77. public class TheClass
  78. {
  79. }
  80. public class TheDependentClass
  81. {
  82. public TheDependentClass(TheClass dependent)
  83. {
  84. _dependent = dependent;
  85. }
  86. TheClass _dependent;
  87. public TheClass Dependent
  88. {
  89. get { return _dependent; }
  90. }
  91. }
  92. void WhenClearingStore()
  93. {
  94. InMemoryStore.Clear();
  95. }
  96. void GivenInMemoryStore()
  97. {
  98. InMemoryStore = new InMemoryContextStore();
  99. Resolver.AddDependencyInstance<IContextStore>(InMemoryStore);
  100. }
  101. [Test]
  102. public void a_dependency_registered_in_one_context_is_not_registered_in_another()
  103. {
  104. var objectForScope1 = new TheClass();
  105. var scope1 = new AmbientContext();
  106. var scope2 = new AmbientContext();
  107. Resolver.AddDependency<IContextStore, AmbientContextStore>();
  108. using (new ContextScope(scope1))
  109. Resolver.AddDependencyInstance<TheClass>(objectForScope1, DependencyLifetime.PerRequest);
  110. using (new ContextScope(scope2))
  111. {
  112. Resolver.HasDependency(typeof (TheClass)).ShouldBeFalse();
  113. Executing(() => Resolver.Resolve<TheClass>()).ShouldThrow<DependencyResolutionException>();
  114. }
  115. }
  116. [Test]
  117. public void a_type_registered_as_per_request_cannot_be_resolved_if_IContextStore_is_not_registered()
  118. {
  119. Resolver.AddDependency<ISimple, Simple>(DependencyLifetime.PerRequest);
  120. Executing(() => Resolver.Resolve<ISimple>())
  121. .ShouldThrow<DependencyResolutionException>();
  122. }
  123. [Test]
  124. public void a_type_registered_as_transient_gets_an_instance_stored_in_context_injected()
  125. {
  126. Resolver.AddDependency<IContextStore, AmbientContextStore>();
  127. var objectForScope = new TheClass();
  128. var scope = new AmbientContext();
  129. Resolver.AddDependency<TheDependentClass>(DependencyLifetime.Transient);
  130. using(new ContextScope(scope))
  131. {
  132. Resolver.AddDependencyInstance(typeof(TheClass),objectForScope,DependencyLifetime.PerRequest);
  133. var dependentClass = Resolver.Resolve<TheDependentClass>();
  134. dependentClass.ShouldNotBeNull();
  135. dependentClass.Dependent.ShouldBeTheSameInstanceAs(objectForScope);
  136. }
  137. }
  138. [Test]
  139. public void instance_registered_as_per_request_are_cleared_when_context_store_is_terminating()
  140. {
  141. GivenInMemoryStore();
  142. var firstInstance = new TheClass();
  143. Resolver.AddDependencyInstance<TheClass>(firstInstance, DependencyLifetime.PerRequest);
  144. Resolver.Resolve<TheClass>().ShouldBeTheSameInstanceAs(firstInstance);
  145. Resolver.HandleIncomingRequestProcessed();
  146. Executing(() => Resolver.Resolve<TheClass>()).ShouldThrow<DependencyResolutionException>();
  147. }
  148. [Test]
  149. public void non_instance_registrations_are_created_for_each_context_store()
  150. {
  151. GivenInMemoryStore();
  152. Resolver.AddDependency<Customer>(DependencyLifetime.PerRequest);
  153. var instance = Resolver.Resolve<Customer>();
  154. var anotherInstanceInSameContext = Resolver.Resolve<Customer>();
  155. instance.ShouldBeTheSameInstanceAs(anotherInstanceInSameContext);
  156. WhenClearingStore();
  157. var instance2 = Resolver.Resolve<Customer>();
  158. instance.ShouldNotBeTheSameInstanceAs(instance2);
  159. }
  160. [Test]
  161. public void registering_instances_in_different_scopes_results_in_each_consumer_getting_the_correct_registration()
  162. {
  163. var objectForScope1 = new TheClass();
  164. var objectForScope2 = new TheClass();
  165. var scope1 = new AmbientContext();
  166. var scope2 = new AmbientContext();
  167. Resolver.AddDependency<IContextStore, AmbientContextStore>();
  168. using (new ContextScope(scope1))
  169. Resolver.AddDependencyInstance<TheClass>(objectForScope1, DependencyLifetime.PerRequest);
  170. using (new ContextScope(scope2))
  171. Resolver.AddDependencyInstance<TheClass>(objectForScope2, DependencyLifetime.PerRequest);
  172. using (new ContextScope(scope1))
  173. {
  174. Resolver.Resolve<TheClass>().ShouldBeTheSameInstanceAs(objectForScope1);
  175. }
  176. }
  177. [Test]
  178. public void registering_instances_in_different_scopes_results_in_only_the_context_specific_registrations_to_be_resolved_in_a_context()
  179. {
  180. var objectForScope1 = new TheClass();
  181. var objectForScope2 = new TheClass();
  182. var scope1 = new AmbientContext();
  183. var scope2 = new AmbientContext();
  184. Resolver.AddDependency<IContextStore, AmbientContextStore>();
  185. using (new ContextScope(scope1))
  186. Resolver.AddDependencyInstance<TheClass>(objectForScope1, DependencyLifetime.PerRequest);
  187. using (new ContextScope(scope2))
  188. Resolver.AddDependencyInstance<TheClass>(objectForScope2, DependencyLifetime.PerRequest);
  189. using (new ContextScope(scope1))
  190. {
  191. Resolver.ResolveAll<TheClass>()
  192. .ShouldContain(objectForScope1)
  193. .Count().ShouldBe(1);
  194. }
  195. }
  196. [Test]
  197. public void registering_two_instances_for_the_same_type_resolves_at_least_one_entry()
  198. {
  199. GivenInMemoryStore();
  200. var firstInstance = new TheClass();
  201. var secondInstance = new TheClass();
  202. Resolver.AddDependencyInstance<TheClass>(firstInstance, DependencyLifetime.PerRequest);
  203. Resolver.AddDependencyInstance<TheClass>(secondInstance, DependencyLifetime.PerRequest);
  204. var result = Resolver.ResolveAll<TheClass>();
  205. (result.Contains(firstInstance) || result.Contains(secondInstance))
  206. .ShouldBeTrue();
  207. }
  208. }
  209. public abstract class when_registering_dependencies : dependency_resolver_context
  210. {
  211. [Test]
  212. public void an_abstract_type_cannot_be_registered()
  213. {
  214. Executing(() => Resolver.AddDependency<ISimple, SimpleAbstract>())
  215. .ShouldThrow<InvalidOperationException>();
  216. }
  217. [Test]
  218. public void an_interface_cannot_be_registered_as_a_concrete_implementation()
  219. {
  220. Executing(() => Resolver.AddDependency<ISimple, IAnotherSimple>())
  221. .ShouldThrow<InvalidOperationException>();
  222. }
  223. [Test]
  224. public void cyclic_dependency_generates_an_error()
  225. {
  226. Resolver.AddDependency<RecursiveConstructor>();
  227. Executing(() => Resolver.Resolve<RecursiveConstructor>())
  228. .ShouldThrow<DependencyResolutionException>();
  229. }
  230. [Test]
  231. public void parameters_are_resolved()
  232. {
  233. Resolver.AddDependency<ISimple, Simple>();
  234. Resolver.AddDependency<ISimpleChild, SimpleChild>();
  235. ((Simple) Resolver.Resolve<ISimple>()).Property
  236. .ShouldNotBeNull()
  237. .ShouldBeOfType<SimpleChild>();
  238. }
  239. [Test]
  240. public void registered_concrete_type_is_recognized_as_dependency_implementation()
  241. {
  242. Resolver.AddDependency<ISimple, Simple>();
  243. Resolver.HasDependencyImplementation(typeof (ISimple), typeof (Simple)).ShouldBeTrue();
  244. }
  245. [Test]
  246. public void registering_a_concrete_type_results_in_the_type_being_registered()
  247. {
  248. Resolver.AddDependency(typeof (Simple), DependencyLifetime.Transient);
  249. Resolver.HasDependency(typeof (Simple))
  250. .ShouldBeTrue();
  251. }
  252. [Test]
  253. public void registering_a_concrete_type_with_an_unknown_dependency_lifetime_value_results_in__an_error()
  254. {
  255. Executing(() => Resolver.AddDependency<Simple>((DependencyLifetime) 999))
  256. .ShouldThrow<InvalidOperationException>();
  257. }
  258. [Test]
  259. public void registering_a_service_type_with_an_unknown_dependency_lifetime_value_results_in__an_error()
  260. {
  261. Executing(() => Resolver.AddDependency<ISimple, Simple>((DependencyLifetime) 999))
  262. .ShouldThrow<InvalidOperationException>();
  263. }
  264. [Test]
  265. public void requesting_a_type_with_a_public_constructor_returns_a_new_instance_of_that_type()
  266. {
  267. Resolver.AddDependency<ISimple, Simple>();
  268. Resolver.Resolve<ISimple>().ShouldBeOfType<Simple>();
  269. }
  270. [Test]
  271. public void requesting_a_type_with_no_public_constructor_will_return_a_type_with_the_correct_dependency()
  272. {
  273. Resolver.AddDependency<ISimple, Simple>();
  274. Resolver.AddDependency<IAnother, Another>();
  275. ((Another) Resolver.Resolve<IAnother>()).Dependent.ShouldBeOfType<Simple>();
  276. }
  277. [Test]
  278. public void the_constructor_with_the_most_matching_arguments_is_used()
  279. {
  280. Resolver.AddDependency<ISimple, Simple>();
  281. Resolver.AddDependency<IAnother, Another>();
  282. Resolver.AddDependency<TypeWithTwoConstructors>();
  283. var type = Resolver.Resolve<TypeWithTwoConstructors>();
  284. type._argOne.ShouldNotBeNull();
  285. type._argTwo.ShouldNotBeNull();
  286. }
  287. [Test]
  288. public void the_null_value_is_never_registered()
  289. {
  290. Resolver.HasDependency(null).ShouldBeFalse();
  291. }
  292. [Test]
  293. public void the_resolved_instance_is_the_same_as_the_registered_instance()
  294. {
  295. string objectInstance = "some object";
  296. Resolver.AddDependencyInstance(typeof (string), objectInstance);
  297. Resolver.Resolve<string>().ShouldBe(objectInstance);
  298. }
  299. }
  300. }
  301. #region Full license
  302. //
  303. // Permission is hereby granted, free of charge, to any person obtaining
  304. // a copy of this software and associated documentation files (the
  305. // "Software"), to deal in the Software without restriction, including
  306. // without limitation the rights to use, copy, modify, merge, publish,
  307. // distribute, sublicense, and/or sell copies of the Software, and to
  308. // permit persons to whom the Software is furnished to do so, subject to
  309. // the following conditions:
  310. //
  311. // The above copyright notice and this permission notice shall be
  312. // included in all copies or substantial portions of the Software.
  313. //
  314. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  315. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  316. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  317. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  318. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  319. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  320. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  321. //
  322. #endregion