1 // Copyright 2004-2007 Castle Project - http://www.castleproject.org/
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 namespace Castle
.MicroKernel
.Tests
.SubContainers
18 using System
.Collections
;
20 using Castle
.MicroKernel
.Tests
.ClassComponents
;
21 using NUnit
.Framework
;
24 /// Summary description for SubContainersTestCase.
27 public class SubContainersTestCase
29 private IKernel kernel
;
34 kernel
= new DefaultKernel();
44 public void ChildDependenciesSatisfiedAmongContainers()
46 IKernel subkernel
= new DefaultKernel();
48 kernel
.AddComponent("templateengine", typeof(DefaultTemplateEngine
));
49 kernel
.AddComponent("mailsender", typeof(DefaultMailSenderService
));
51 kernel
.AddChildKernel(subkernel
);
52 subkernel
.AddComponent("spamservice", typeof(DefaultSpamService
));
54 DefaultSpamService spamservice
= (DefaultSpamService
) subkernel
["spamservice"];
56 Assert
.IsNotNull(spamservice
);
57 Assert
.IsNotNull(spamservice
.MailSender
);
58 Assert
.IsNotNull(spamservice
.TemplateEngine
);
62 public void ChildDependenciesIsSatisfiedEvenWhenComponentTakesLongToBeAddedToParentContainer()
64 DefaultKernel container
= new DefaultKernel();
65 DefaultKernel childContainer
= new DefaultKernel();
67 container
.AddChildKernel(childContainer
);
68 childContainer
.AddComponent("component", typeof(Component
));
70 container
.AddComponent("service1", typeof(IService
), typeof(Service
));
72 Component comp
= (Component
) childContainer
[typeof(Component
)];
75 [Test
, Ignore("This need to be discussed")]
76 public void SameLevelDependenciesSatisfied()
78 IKernel child
= new DefaultKernel();
80 kernel
.AddComponent("templateengine", typeof(DefaultTemplateEngine
));
81 kernel
.AddComponent("spamservice", typeof(DefaultSpamService
));
83 kernel
.AddChildKernel(child
);
85 child
.AddComponent("mailsender", typeof(DefaultMailSenderService
));
87 DefaultSpamService spamservice
= (DefaultSpamService
) child
["spamservice"];
89 Assert
.IsNotNull(spamservice
);
90 Assert
.IsNotNull(spamservice
.MailSender
);
91 Assert
.IsNotNull(spamservice
.TemplateEngine
);
94 [Test
, Ignore("This is not passing, and anyway, the goal should be reviewed")]
95 public void UseChildComponentsForParentDependenciesWhenRequestedFromChild()
97 IKernel subkernel
= new DefaultKernel();
99 kernel
.AddComponent("spamservice", typeof(DefaultSpamService
), LifestyleType
.Transient
);
100 kernel
.AddComponent("mailsender", typeof(DefaultMailSenderService
));
101 kernel
.AddComponent("templateengine", typeof(DefaultTemplateEngine
));
103 kernel
.AddChildKernel(subkernel
);
104 subkernel
.AddComponent("templateengine", typeof(DefaultTemplateEngine
));
106 DefaultTemplateEngine templateengine
= (DefaultTemplateEngine
) kernel
["templateengine"];
107 DefaultTemplateEngine sub_templateengine
= (DefaultTemplateEngine
) subkernel
["templateengine"];
109 DefaultSpamService spamservice
= (DefaultSpamService
) subkernel
["spamservice"];
110 Assert
.AreNotEqual(spamservice
.TemplateEngine
, templateengine
);
111 Assert
.AreEqual(spamservice
.TemplateEngine
, sub_templateengine
);
113 spamservice
= (DefaultSpamService
) kernel
["spamservice"];
114 Assert
.AreNotEqual(spamservice
.TemplateEngine
, sub_templateengine
);
115 Assert
.AreEqual(spamservice
.TemplateEngine
, templateengine
);
117 kernel
.RemoveComponent("templateengine");
118 spamservice
= (DefaultSpamService
) kernel
["spamservice"];
119 Assert
.IsNull(spamservice
.TemplateEngine
);
122 [Test
, Ignore("This is not passing, and anyway, the goal should be reviewed")]
123 public void Singleton_WithNonSingletonDependencies_DoesNotReResolveDependencies()
125 kernel
.AddComponent("spamservice", typeof(DefaultSpamService
));
126 kernel
.AddComponent("mailsender", typeof(DefaultMailSenderService
));
128 IKernel subkernel1
= new DefaultKernel();
129 subkernel1
.AddComponent("templateengine", typeof(DefaultTemplateEngine
));
130 kernel
.AddChildKernel(subkernel1
);
132 IKernel subkernel2
= new DefaultKernel();
133 subkernel2
.AddComponent("templateengine", typeof(DefaultTemplateEngine
), LifestyleType
.Transient
);
134 kernel
.AddChildKernel(subkernel2
);
136 DefaultTemplateEngine templateengine1
= (DefaultTemplateEngine
) subkernel1
["templateengine"];
137 DefaultSpamService spamservice1
= (DefaultSpamService
) subkernel1
["spamservice"];
138 Assert
.IsNotNull(spamservice1
);
139 Assert
.AreEqual(spamservice1
.TemplateEngine
.Key
, templateengine1
.Key
);
141 DefaultTemplateEngine templateengine2
= (DefaultTemplateEngine
) subkernel2
["templateengine"];
142 DefaultSpamService spamservice2
= (DefaultSpamService
) subkernel2
["spamservice"];
143 Assert
.IsNotNull(spamservice2
);
144 Assert
.AreEqual(spamservice1
, spamservice2
);
145 Assert
.AreEqual(spamservice1
.TemplateEngine
.Key
, templateengine1
.Key
);
146 Assert
.AreNotEqual(spamservice2
.TemplateEngine
.Key
, templateengine2
.Key
);
150 public void DependenciesSatisfiedAmongContainers()
152 IKernel subkernel
= new DefaultKernel();
154 kernel
.AddComponent("mailsender", typeof(DefaultMailSenderService
));
155 kernel
.AddComponent("templateengine", typeof(DefaultTemplateEngine
));
157 kernel
.AddChildKernel(subkernel
);
159 subkernel
.AddComponent("spamservice", typeof(DefaultSpamService
));
161 DefaultSpamService spamservice
= (DefaultSpamService
) subkernel
["spamservice"];
163 Assert
.IsNotNull(spamservice
);
164 Assert
.IsNotNull(spamservice
.MailSender
);
165 Assert
.IsNotNull(spamservice
.TemplateEngine
);
169 public void DependenciesSatisfiedAmongContainersUsingEvents()
171 IKernel subkernel
= new DefaultKernel();
173 subkernel
.AddComponent("spamservice", typeof(DefaultSpamServiceWithConstructor
));
175 kernel
.AddComponent("mailsender", typeof(DefaultMailSenderService
));
176 kernel
.AddComponent("templateengine", typeof(DefaultTemplateEngine
));
178 kernel
.AddChildKernel(subkernel
);
180 DefaultSpamServiceWithConstructor spamservice
=
181 (DefaultSpamServiceWithConstructor
) subkernel
["spamservice"];
183 Assert
.IsNotNull(spamservice
);
184 Assert
.IsNotNull(spamservice
.MailSender
);
185 Assert
.IsNotNull(spamservice
.TemplateEngine
);
189 public void ChildKernelFindsAndCreateParentComponent()
191 IKernel subkernel
= new DefaultKernel();
193 kernel
.AddComponent("templateengine", typeof(DefaultTemplateEngine
));
195 kernel
.AddChildKernel(subkernel
);
198 Assert
.IsTrue(subkernel
.HasComponent(typeof(DefaultTemplateEngine
)));
199 Assert
.IsNotNull(subkernel
[typeof(DefaultTemplateEngine
)]);
203 [ExpectedException(typeof(ComponentNotFoundException
))]
204 public void ParentKernelFindsAndCreateChildComponent()
206 IKernel subkernel
= new DefaultKernel();
208 subkernel
.AddComponent("templateengine", typeof(DefaultTemplateEngine
));
210 kernel
.AddChildKernel(subkernel
);
213 Assert
.IsFalse(kernel
.HasComponent(typeof(DefaultTemplateEngine
)));
214 object engine
= kernel
[typeof(DefaultTemplateEngine
)];
218 public void ChildKernelOverloadsParentKernel1()
220 DefaultTemplateEngine instance1
= new DefaultTemplateEngine();
221 DefaultTemplateEngine instance2
= new DefaultTemplateEngine();
223 // subkernel added with already registered components that overload parent components.
225 IKernel subkernel
= new DefaultKernel();
226 subkernel
.AddComponentInstance("engine", instance1
);
227 Assert
.AreEqual(instance1
, subkernel
["engine"]);
229 kernel
.AddComponentInstance("engine", instance2
);
230 Assert
.AreEqual(instance2
, kernel
["engine"]);
232 kernel
.AddChildKernel(subkernel
);
233 Assert
.AreEqual(instance1
, subkernel
["engine"]);
234 Assert
.AreEqual(instance2
, kernel
["engine"]);
238 public void ChildKernelOverloadsParentKernel2()
240 DefaultTemplateEngine instance1
= new DefaultTemplateEngine();
241 DefaultTemplateEngine instance2
= new DefaultTemplateEngine();
243 IKernel subkernel
= new DefaultKernel();
244 kernel
.AddChildKernel(subkernel
);
246 // subkernel added first, then populated with overloaded components after
248 kernel
.AddComponentInstance("engine", instance2
);
249 Assert
.AreEqual(instance2
, kernel
["engine"]);
250 Assert
.AreEqual(instance2
, subkernel
["engine"]);
252 subkernel
.AddComponentInstance("engine", instance1
);
253 Assert
.AreEqual(instance1
, subkernel
["engine"]);
254 Assert
.AreEqual(instance2
, kernel
["engine"]);
258 public void RemoveChildKernelCleansUp()
260 IKernel subkernel
= new DefaultKernel();
261 EventsCollector eventCollector
= new EventsCollector(subkernel
);
262 subkernel
.RemovedAsChildKernel
+= new EventHandler(eventCollector
.RemovedAsChildKernel
);
263 subkernel
.AddedAsChildKernel
+= new EventHandler(eventCollector
.AddedAsChildKernel
);
265 kernel
.AddChildKernel(subkernel
);
266 Assert
.AreEqual(kernel
, subkernel
.Parent
);
267 Assert
.AreEqual(1, eventCollector
.Events
.Count
);
268 Assert
.AreEqual(EventsCollector
.Added
, eventCollector
.Events
[0]);
270 kernel
.RemoveChildKernel(subkernel
);
271 Assert
.IsNull(subkernel
.Parent
);
272 Assert
.AreEqual(2, eventCollector
.Events
.Count
);
273 Assert
.AreEqual(EventsCollector
.Removed
, eventCollector
.Events
[1]);
277 [ExpectedException(typeof(KernelException
),
278 "You can not change the kernel parent once set, use the RemoveChildKernel and AddChildKernel methods together to achieve this."
280 public void AddChildKernelToTwoParentsThrowsException()
282 IKernel kernel2
= new DefaultKernel();
284 IKernel subkernel
= new DefaultKernel();
286 kernel
.AddChildKernel(subkernel
);
287 Assert
.AreEqual(kernel
, subkernel
.Parent
);
289 kernel2
.AddChildKernel(subkernel
);
293 public void RemovingChildKernelUnsubscribesFromParentEvents()
295 IKernel subkernel
= new DefaultKernel();
296 EventsCollector eventCollector
= new EventsCollector(subkernel
);
297 subkernel
.RemovedAsChildKernel
+= new EventHandler(eventCollector
.RemovedAsChildKernel
);
298 subkernel
.AddedAsChildKernel
+= new EventHandler(eventCollector
.AddedAsChildKernel
);
300 kernel
.AddChildKernel(subkernel
);
301 kernel
.RemoveChildKernel(subkernel
);
302 kernel
.AddChildKernel(subkernel
);
303 kernel
.RemoveChildKernel(subkernel
);
305 Assert
.AreEqual(4, eventCollector
.Events
.Count
);
306 Assert
.AreEqual(EventsCollector
.Added
, eventCollector
.Events
[0]);
307 Assert
.AreEqual(EventsCollector
.Removed
, eventCollector
.Events
[1]);
308 Assert
.AreEqual(EventsCollector
.Added
, eventCollector
.Events
[2]);
309 Assert
.AreEqual(EventsCollector
.Removed
, eventCollector
.Events
[3]);
313 /// collects events in an array list, used for ensuring we are cleaning up the parent kernel
314 /// event subscriptions correctly.
316 private class EventsCollector
318 public const string Added
= "added";
319 public const string Removed
= "removed";
321 private ArrayList events
;
322 private object expectedSender
;
324 public ArrayList Events
326 get { return events; }
329 public EventsCollector(object expectedSender
)
331 this.expectedSender
= expectedSender
;
332 events
= new ArrayList();
335 public void AddedAsChildKernel(object sender
, EventArgs e
)
337 Assert
.AreEqual(expectedSender
, sender
);
341 public void RemovedAsChildKernel(object sender
, EventArgs e
)
343 Assert
.AreEqual(expectedSender
, sender
);
348 public class Component
350 public Component(IService service
)
355 public interface IService
359 public class Service
: IService