PageRenderTime 58ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/src/Ninject.Test/Integration/StandardKernelTests.cs

https://github.com/wjkhappy14/ninject
C# | 519 lines | 420 code | 99 blank | 0 comment | 1 complexity | d1eb427336c3598c3c8b1cd40ea5d089 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, BSD-3-Clause
  1. namespace Ninject.Tests.Integration.StandardKernelTests
  2. {
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using FluentAssertions;
  7. using Ninject.Parameters;
  8. using Ninject.Tests.Fakes;
  9. using Xunit;
  10. public class StandardKernelContext : IDisposable
  11. {
  12. protected StandardKernel kernel;
  13. public StandardKernelContext()
  14. {
  15. this.kernel = new StandardKernel();
  16. }
  17. public void Dispose()
  18. {
  19. this.kernel.Dispose();
  20. }
  21. }
  22. public class WhenGetIsCalledForInterfaceBoundService : StandardKernelContext
  23. {
  24. [Fact]
  25. public void SingleInstanceIsReturnedWhenOneBindingIsRegistered()
  26. {
  27. kernel.Bind<IWeapon>().To<Sword>();
  28. var weapon = kernel.Get<IWeapon>();
  29. weapon.Should().NotBeNull();
  30. weapon.Should().BeOfType<Sword>();
  31. }
  32. [Fact]
  33. public void ActivationExceptionThrownWhenMultipleBindingsAreRegistered()
  34. {
  35. kernel.Bind<IWeapon>().To<Sword>();
  36. kernel.Bind<IWeapon>().To<Shuriken>();
  37. var exception = Assert.Throws<ActivationException>(() => kernel.Get<IWeapon>());
  38. exception.Message.Should().Contain("More than one matching bindings are available.");
  39. exception.Message.Should().Contain("1) binding from IWeapon to Sword");
  40. exception.Message.Should().Contain("2) binding from IWeapon to Shuriken");
  41. }
  42. [Fact]
  43. public void DependenciesAreInjectedViaConstructor()
  44. {
  45. kernel.Bind<IWeapon>().To<Sword>();
  46. kernel.Bind<IWarrior>().To<Samurai>();
  47. var warrior = kernel.Get<IWarrior>();
  48. warrior.Should().NotBeNull();
  49. warrior.Should().BeOfType<Samurai>();
  50. warrior.Weapon.Should().NotBeNull();
  51. warrior.Weapon.Should().BeOfType<Sword>();
  52. }
  53. }
  54. public class WhenGetIsCalledForSelfBoundService : StandardKernelContext
  55. {
  56. [Fact]
  57. public void SingleInstanceIsReturnedWhenOneBindingIsRegistered()
  58. {
  59. kernel.Bind<Sword>().ToSelf();
  60. var weapon = kernel.Get<Sword>();
  61. weapon.Should().NotBeNull();
  62. weapon.Should().BeOfType<Sword>();
  63. }
  64. [Fact]
  65. public void DependenciesAreInjectedViaConstructor()
  66. {
  67. kernel.Bind<IWeapon>().To<Sword>();
  68. kernel.Bind<Samurai>().ToSelf();
  69. var samurai = kernel.Get<Samurai>();
  70. samurai.Should().NotBeNull();
  71. samurai.Weapon.Should().NotBeNull();
  72. samurai.Weapon.Should().BeOfType<Sword>();
  73. }
  74. }
  75. public class WhenGetIsCalledForUnboundService : StandardKernelContext
  76. {
  77. [Fact]
  78. public void ImplicitSelfBindingIsRegisteredAndActivated()
  79. {
  80. var weapon = kernel.Get<Sword>();
  81. weapon.Should().NotBeNull();
  82. weapon.Should().BeOfType<Sword>();
  83. }
  84. [Fact]
  85. public void ImplicitSelfBindingForGenericTypeIsRegisteredAndActivated()
  86. {
  87. var service = kernel.Get<GenericService<int>>();
  88. service.Should().NotBeNull();
  89. service.Should().BeOfType<GenericService<int>>();
  90. }
  91. [Fact]
  92. public void ThrowsExceptionIfAnUnboundInterfaceIsRequested()
  93. {
  94. Assert.Throws<ActivationException>(() => kernel.Get<IWeapon>());
  95. }
  96. [Fact]
  97. public void ThrowsExceptionIfAnUnboundAbstractClassIsRequested()
  98. {
  99. Assert.Throws<ActivationException>(() => kernel.Get<AbstractWeapon>());
  100. }
  101. [Fact]
  102. public void ThrowsExceptionIfAnUnboundValueTypeIsRequested()
  103. {
  104. Assert.Throws<ActivationException>(() => kernel.Get<int>());
  105. }
  106. [Fact]
  107. public void ThrowsExceptionIfAStringIsRequestedWithNoBinding()
  108. {
  109. Assert.Throws<ActivationException>(() => kernel.Get<string>());
  110. }
  111. [Fact]
  112. public void ThrowsExceptionIfAnOpenGenericTypeIsRequested()
  113. {
  114. Assert.Throws<ActivationException>(() => kernel.Get(typeof(IGeneric<>)));
  115. }
  116. }
  117. public class WhenGetIsCalledForGenericServiceRegisteredViaOpenGenericType : StandardKernelContext
  118. {
  119. [Fact]
  120. public void GenericParametersAreInferred()
  121. {
  122. kernel.Bind(typeof(IGeneric<>)).To(typeof(GenericService<>));
  123. var service = kernel.Get<IGeneric<int>>();
  124. service.Should().NotBeNull();
  125. service.Should().BeOfType<GenericService<int>>();
  126. }
  127. }
  128. public class WhenTryGetIsCalledForInterfaceBoundService : StandardKernelContext
  129. {
  130. [Fact]
  131. public void SingleInstanceIsReturnedWhenOneBindingIsRegistered()
  132. {
  133. kernel.Bind<IWeapon>().To<Sword>();
  134. var weapon = kernel.TryGet<IWeapon>();
  135. weapon.Should().NotBeNull();
  136. weapon.Should().BeOfType<Sword>();
  137. }
  138. [Fact]
  139. public void NullIsReturnedWhenMultipleBindingsAreRegistered()
  140. {
  141. kernel.Bind<IWeapon>().To<Sword>();
  142. kernel.Bind<IWeapon>().To<Shuriken>();
  143. var weapon = kernel.TryGet<IWeapon>();
  144. weapon.Should().BeNull();
  145. }
  146. }
  147. public class WhenTryGetIsCalledForUnboundService : StandardKernelContext
  148. {
  149. [Fact]
  150. public void ImplicitSelfBindingIsRegisteredAndActivatedIfTypeIsSelfBindable()
  151. {
  152. var weapon = kernel.TryGet<Sword>();
  153. weapon.Should().NotBeNull();
  154. weapon.Should().BeOfType<Sword>();
  155. }
  156. [Fact]
  157. public void ReturnsNullIfTypeIsNotSelfBindable()
  158. {
  159. var weapon = kernel.TryGet<IWeapon>();
  160. weapon.Should().BeNull();
  161. }
  162. [Fact]
  163. public void ReturnsNullIfTypeHasOnlyUnmetConditionalBindings()
  164. {
  165. this.kernel.Bind<IWeapon>().To<Sword>().When(ctx => false);
  166. var weapon = kernel.TryGet<IWeapon>();
  167. weapon.Should().BeNull();
  168. }
  169. [Fact]
  170. public void ReturnsNullIfNoBindingForADependencyExists()
  171. {
  172. this.kernel.Bind<IWarrior>().To<Samurai>();
  173. var warrior = kernel.TryGet<IWarrior>();
  174. warrior.Should().BeNull();
  175. }
  176. [Fact]
  177. public void ReturnsNullIfMultipleBindingsExistForADependency()
  178. {
  179. this.kernel.Bind<IWarrior>().To<Samurai>();
  180. kernel.Bind<IWeapon>().To<Sword>();
  181. kernel.Bind<IWeapon>().To<Shuriken>();
  182. var warrior = kernel.TryGet<IWarrior>();
  183. warrior.Should().BeNull();
  184. }
  185. [Fact]
  186. public void ReturnsNullIfOnlyUnmetConditionalBindingsExistForADependency()
  187. {
  188. this.kernel.Bind<IWarrior>().To<Samurai>();
  189. kernel.Bind<IWeapon>().To<Sword>().When(ctx => false);
  190. var warrior = kernel.TryGet<IWarrior>();
  191. warrior.Should().BeNull();
  192. }
  193. }
  194. public class WhenGetAllIsCalledForInterfaceBoundService : StandardKernelContext
  195. {
  196. [Fact]
  197. public void ReturnsSeriesOfItemsInOrderTheyWereBound()
  198. {
  199. kernel.Bind<IWeapon>().To<Sword>();
  200. kernel.Bind<IWeapon>().To<Shuriken>();
  201. var weapons = kernel.GetAll<IWeapon>().ToArray();
  202. weapons.Should().NotBeNull();
  203. weapons.Length.Should().Be(2);
  204. weapons[0].Should().BeOfType<Sword>();
  205. weapons[1].Should().BeOfType<Shuriken>();
  206. }
  207. [Fact]
  208. public void DoesNotActivateItemsUntilTheEnumeratorRunsOverThem()
  209. {
  210. InitializableA.Count = 0;
  211. InitializableB.Count = 0;
  212. kernel.Bind<IInitializable>().To<InitializableA>();
  213. kernel.Bind<IInitializable>().To<InitializableB>();
  214. IEnumerable<IInitializable> instances = kernel.GetAll<IInitializable>();
  215. IEnumerator<IInitializable> enumerator = instances.GetEnumerator();
  216. InitializableA.Count.Should().Be(0);
  217. enumerator.MoveNext();
  218. InitializableA.Count.Should().Be(1);
  219. InitializableB.Count.Should().Be(0);
  220. enumerator.MoveNext();
  221. InitializableA.Count.Should().Be(1);
  222. InitializableB.Count.Should().Be(1);
  223. }
  224. }
  225. public class WhenGetAllIsCalledForGenericServiceRegisteredViaOpenGenericType : StandardKernelContext
  226. {
  227. [Fact]
  228. public void GenericParametersAreInferred()
  229. {
  230. kernel.Bind(typeof(IGeneric<>)).To(typeof(GenericService<>));
  231. kernel.Bind(typeof(IGeneric<>)).To(typeof(GenericService2<>));
  232. var services = kernel.GetAll<IGeneric<int>>().ToArray();
  233. services.Should().NotBeNull();
  234. services.Length.Should().Be(2);
  235. services[0].Should().BeOfType<GenericService<int>>();
  236. services[1].Should().BeOfType<GenericService2<int>>();
  237. }
  238. [Fact]
  239. public void OpenGenericBindingsCanBeOverridenByClosedGenericBindings()
  240. {
  241. kernel.Bind(typeof(IGeneric<>)).To(typeof(GenericService<>));
  242. kernel.Bind<IGeneric<int>>().To<ClosedGenericService>();
  243. var service = kernel.Get<IGeneric<int>>();
  244. service.Should().BeOfType<ClosedGenericService>();
  245. }
  246. #if NET_40
  247. [Fact]
  248. public void OpenGenericsWithCoAndContraVarianceCanBeResolved()
  249. {
  250. kernel.Bind(typeof(IGenericCoContraVarianceService<,>)).To(typeof(OpenGenericCoContraVarianceService<,>));
  251. var service = kernel.Get<IGenericCoContraVarianceService<string, int>>();
  252. service.Should().BeOfType<OpenGenericCoContraVarianceService<string, int>>();
  253. }
  254. [Fact]
  255. public void ClosedGenericsWithCoAndContraVarianceCanBeResolved()
  256. {
  257. kernel.Bind(typeof(IGenericCoContraVarianceService<string, int>)).To(typeof(ClosedGenericCoContraVarianceService));
  258. var service = kernel.Get<IGenericCoContraVarianceService<string, int>>();
  259. service.Should().BeOfType<ClosedGenericCoContraVarianceService>();
  260. }
  261. #endif
  262. }
  263. public class WhenGetAllIsCalledForUnboundService : StandardKernelContext
  264. {
  265. [Fact]
  266. public void ImplicitSelfBindingIsRegisteredAndActivatedIfTypeIsSelfBindable()
  267. {
  268. var weapons = kernel.GetAll<Sword>().ToArray();
  269. weapons.Should().NotBeNull();
  270. weapons.Length.Should().Be(1);
  271. weapons[0].Should().BeOfType<Sword>();
  272. }
  273. [Fact]
  274. public void ReturnsEmptyEnumerableIfTypeIsNotSelfBindable()
  275. {
  276. var weapons = kernel.GetAll<IWeapon>().ToArray();
  277. weapons.Should().NotBeNull();
  278. weapons.Length.Should().Be(0);
  279. }
  280. }
  281. public class WhenGetIsCalledForProviderBoundService : StandardKernelContext
  282. {
  283. [Fact]
  284. public void WhenProviderReturnsNullThenActivationExceptionIsThrown()
  285. {
  286. kernel.Bind<IWeapon>().ToProvider<NullProvider>();
  287. Assert.Throws<Ninject.ActivationException>(() => kernel.Get<IWeapon>());
  288. }
  289. [Fact]
  290. public void WhenProviderReturnsNullButAllowedInSettingsThenNullIsResolved()
  291. {
  292. kernel.Settings.AllowNullInjection = true;
  293. kernel.Bind<IWeapon>().ToProvider<NullProvider>();
  294. var weapon = kernel.Get<IWeapon>();
  295. weapon.Should().BeNull();
  296. }
  297. }
  298. public class WhenGetIsCalledWithConstraints : StandardKernelContext
  299. {
  300. [Fact]
  301. public void ReturnsServiceRegisteredViaBindingWithSpecifiedName()
  302. {
  303. kernel.Bind<IWeapon>().To<Shuriken>();
  304. kernel.Bind<IWeapon>().To<Sword>().Named("sword");
  305. var weapon = kernel.Get<IWeapon>("sword");
  306. weapon.Should().NotBeNull();
  307. weapon.Should().BeOfType<Sword>();
  308. }
  309. [Fact]
  310. public void ReturnsServiceRegisteredViaBindingThatMatchesPredicate()
  311. {
  312. kernel.Bind<IWeapon>().To<Shuriken>().WithMetadata("type", "range");
  313. kernel.Bind<IWeapon>().To<Sword>().WithMetadata("type", "melee");
  314. var weapon = kernel.Get<IWeapon>(x => x.Get<string>("type") == "melee");
  315. weapon.Should().NotBeNull();
  316. weapon.Should().BeOfType<Sword>();
  317. }
  318. }
  319. public class WhenUnbindIsCalled : StandardKernelContext
  320. {
  321. [Fact]
  322. public void RemovesAllBindingsForService()
  323. {
  324. kernel.Bind<IWeapon>().To<Shuriken>();
  325. kernel.Bind<IWeapon>().To<Sword>();
  326. var bindings = kernel.GetBindings(typeof(IWeapon)).ToArray();
  327. bindings.Length.Should().Be(2);
  328. kernel.Unbind<IWeapon>();
  329. bindings = kernel.GetBindings(typeof(IWeapon)).ToArray();
  330. bindings.Should().BeEmpty();
  331. }
  332. }
  333. public class WhenRebindIsCalled : StandardKernelContext
  334. {
  335. [Fact]
  336. public void RemovesAllBindingsForServiceAndReplacesWithSpecifiedBinding()
  337. {
  338. kernel.Bind<IWeapon>().To<Shuriken>();
  339. kernel.Bind<IWeapon>().To<Sword>();
  340. var bindings = kernel.GetBindings(typeof(IWeapon)).ToArray();
  341. bindings.Length.Should().Be(2);
  342. kernel.Rebind<IWeapon>().To<Sword>();
  343. bindings = kernel.GetBindings(typeof(IWeapon)).ToArray();
  344. bindings.Length.Should().Be(1);
  345. }
  346. }
  347. public class WhenCanResolveIsCalled : StandardKernelContext
  348. {
  349. [Fact]
  350. public void ForImplicitBindings()
  351. {
  352. this.kernel.Get<Sword>();
  353. var request = this.kernel.CreateRequest(typeof(Sword), null, Enumerable.Empty<IParameter>(), false, true);
  354. this.kernel.CanResolve(request, true).Should().BeFalse();
  355. this.kernel.CanResolve(request, false).Should().BeTrue();
  356. this.kernel.CanResolve(request).Should().BeTrue();
  357. }
  358. }
  359. #if !SILVERLIGHT
  360. public class WhenDerivedClassWithPrivateGetterIsResolved
  361. {
  362. [Fact]
  363. public void ItCanBeResolved()
  364. {
  365. using (var kernel = new StandardKernel(
  366. new NinjectSettings
  367. {
  368. UseReflectionBasedInjection = true,
  369. InjectNonPublic = true,
  370. InjectParentPrivateProperties = true
  371. }))
  372. {
  373. kernel.Get<DerivedClassWithPrivateGetter>();
  374. }
  375. }
  376. }
  377. #endif
  378. public class InitializableA : IInitializable
  379. {
  380. public static int Count = 0;
  381. public void Initialize()
  382. {
  383. Count++;
  384. }
  385. }
  386. public class InitializableB : IInitializable
  387. {
  388. public static int Count = 0;
  389. public void Initialize()
  390. {
  391. Count++;
  392. }
  393. }
  394. public class ClassWithPrivateGetter
  395. {
  396. float Value
  397. {
  398. get { return 0f; }
  399. }
  400. }
  401. public class DerivedClassWithPrivateGetter : ClassWithPrivateGetter { }
  402. public interface IGeneric<T> { }
  403. public class GenericService<T> : IGeneric<T> { }
  404. public class GenericService2<T> : IGeneric<T> { }
  405. public class ClosedGenericService : IGeneric<int> { }
  406. public interface IGenericWithConstraints<T> where T : class { }
  407. public class GenericServiceWithConstraints<T> : IGenericWithConstraints<T> where T : class { }
  408. #if NET_40
  409. public interface IGenericCoContraVarianceService<in T, out TK> {}
  410. public class ClosedGenericCoContraVarianceService : IGenericCoContraVarianceService<string, int> { }
  411. public class OpenGenericCoContraVarianceService<T, TK> : IGenericCoContraVarianceService<T, TK> { }
  412. #endif
  413. public class NullProvider : Ninject.Activation.Provider<Sword>
  414. {
  415. protected override Sword CreateInstance (Activation.IContext context)
  416. {
  417. return null;
  418. }
  419. }
  420. }