1 // Copyright 2004-2008 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.
17 namespace Castle
.Windsor
.Tests
21 using Castle
.Core
.Interceptor
;
22 using Castle
.MicroKernel
.Registration
;
23 using Castle
.Windsor
.Configuration
.Interpreters
;
26 using NUnit
.Framework
;
29 public class WindsorDotNet2Tests
32 public void UsingResolveGenericMethodOverload()
34 IWindsorContainer container
= new WindsorContainer(new XmlInterpreter(GetFilePath("GenericsConfig.xml")));
35 ICalcService svr
= container
.Resolve
<ICalcService
>();
36 Assert
.IsTrue(typeof(CalculatorService
).IsInstanceOfType(svr
));
40 public void ResolveGenericWithId()
42 IWindsorContainer container
= new WindsorContainer(new XmlInterpreter(GetFilePath("GenericsConfig.xml")));
43 ICalcService svr
= container
.Resolve
<ICalcService
>("calc");
44 Assert
.IsTrue(typeof(CalculatorService
).IsInstanceOfType(svr
));
48 public void GetGenericService()
50 IWindsorContainer container
= new WindsorContainer(new XmlInterpreter(GetFilePath("GenericsConfig.xml")));
51 IRepository
<int> repos
= container
.Resolve
<IRepository
<int>>("int.repos.generic");
52 Assert
.IsNotNull(repos
);
53 Assert
.IsTrue(typeof(DemoRepository
<int>).IsInstanceOfType(repos
));
57 public void GetGenericServiceWithDecorator()
59 IWindsorContainer container
= new WindsorContainer(new XmlInterpreter(GetFilePath("GenericsConfig.xml")));
60 IRepository
<int> repos
= container
.Resolve
<IRepository
<int>>("int.repos");
61 Assert
.IsNotNull(repos
);
62 Assert
.IsTrue(typeof(LoggingRepositoryDecorator
<int>).IsInstanceOfType(repos
));
63 Assert
.IsTrue(typeof(DemoRepository
<int>).IsInstanceOfType(((LoggingRepositoryDecorator
<int>)repos
).inner
));
67 public void WillUseDefaultCtorOnGenericComponentIfTryingToResolveOnSameComponent()
69 IWindsorContainer container
=
70 new WindsorContainer(new XmlInterpreter(GetFilePath("RecursiveDecoratorConfig.xml")));
71 LoggingRepositoryDecorator
<int> resolve
=
72 (LoggingRepositoryDecorator
<int>)container
.Resolve
<IRepository
<int>>();
73 Assert
.IsNull(resolve
.inner
);
77 public void GetGenericServiceWithDecorator_GenericDecoratorOnTop()
79 IWindsorContainer container
= new WindsorContainer(new XmlInterpreter(GetFilePath("DecoratorConfig.xml")));
80 IRepository
<int> repos
= container
.Resolve
<IRepository
<int>>();
81 Assert
.IsTrue(typeof(LoggingRepositoryDecorator
<int>).IsInstanceOfType(repos
));
83 Assert
.IsTrue(typeof(LoggingRepositoryDecorator
<int>).IsInstanceOfType(repos
));
84 Assert
.IsTrue(typeof(DemoRepository
<int>).IsInstanceOfType(((LoggingRepositoryDecorator
<int>)repos
).inner
));
86 DemoRepository
<int> inner
= ((LoggingRepositoryDecorator
<int>)repos
).inner
as DemoRepository
<int>;
88 Assert
.AreEqual("second", inner
.Name
);
92 public void InferGenericArgumentForComponentFromPassedType()
94 IWindsorContainer container
=
95 new WindsorContainer(new XmlInterpreter(GetFilePath("GenericDecoratorConfig.xml")));
97 IRepository
<string> repos
= container
.Resolve
<IRepository
<string>>();
98 Assert
.IsTrue(typeof(LoggingRepositoryDecorator
<string>).IsInstanceOfType(repos
));
100 DemoRepository
<string> inner
= ((LoggingRepositoryDecorator
<string>)repos
).inner
as DemoRepository
<string>;
102 Assert
.AreEqual("second", inner
.Name
);
106 public void GetSameInstanceFromGenericType()
108 IWindsorContainer container
=
109 new WindsorContainer(new XmlInterpreter(GetFilePath("GenericDecoratorConfig.xml")));
111 IRepository
<string> repos1
= container
.Resolve
<IRepository
<string>>();
112 IRepository
<string> repos2
= container
.Resolve
<IRepository
<string>>();
114 Assert
.AreSame(repos1
, repos2
);
118 public void GetSameInstanceOfGenericFromTwoDifferentGenericTypes()
120 IWindsorContainer container
=
121 new WindsorContainer(new XmlInterpreter(GetFilePath("GenericDecoratorConfig.xml")));
123 IRepository
<string> repos1
= container
.Resolve
<IRepository
<string>>();
124 IRepository
<string> repos2
= container
.Resolve
<IRepository
<string>>();
126 Assert
.AreSame(repos1
, repos2
);
128 IRepository
<int> repos3
= container
.Resolve
<IRepository
<int>>();
129 IRepository
<int> repos4
= container
.Resolve
<IRepository
<int>>();
131 Assert
.AreSame(repos3
, repos4
);
135 public void ComplexGenericConfiguration_GetGenericRepostiory()
137 IWindsorContainer container
=
138 new WindsorContainer(new XmlInterpreter(GetFilePath("ComplexGenericConfig.xml")));
139 IRepository
<IEmployee
> empRepost
= container
[typeof(IRepository
<IEmployee
>)] as IRepository
<IEmployee
>;
140 Assert
.IsNotNull(empRepost
);
141 Assert
.IsTrue(typeof(LoggingRepositoryDecorator
<IEmployee
>).IsInstanceOfType(empRepost
));
142 LoggingRepositoryDecorator
<IEmployee
> log
= empRepost
as LoggingRepositoryDecorator
<IEmployee
>;
143 IRepository
<IEmployee
> inner
= log
.inner
;
144 Assert
.IsNotNull(inner
);
145 Assert
.IsTrue(typeof(DemoRepository
<IEmployee
>).IsInstanceOfType(inner
));
146 DemoRepository
<IEmployee
> demoEmpRepost
= inner
as DemoRepository
<IEmployee
>;
147 Assert
.AreEqual("Generic Repostiory", demoEmpRepost
.Name
);
148 Assert
.IsNotNull(demoEmpRepost
.Cache
);
149 Assert
.IsTrue(typeof(HashTableCache
<IEmployee
>).IsInstanceOfType(demoEmpRepost
.Cache
));
153 public void ComplexGenericConfiguration_GetReviewRepository_BoundAtConfiguration()
155 IWindsorContainer container
=
156 new WindsorContainer(new XmlInterpreter(GetFilePath("ComplexGenericConfig.xml")));
157 IRepository
<IReviewer
> rev
= container
.Resolve
<IRepository
<IReviewer
>>();
159 Assert
.IsTrue(typeof(ReviewerRepository
).IsInstanceOfType(rev
));
160 ReviewerRepository repos
= rev
as ReviewerRepository
;
161 Assert
.AreEqual("Reviewer Repository", repos
.Name
);
162 Assert
.IsNotNull(repos
.Cache
);
163 Assert
.IsTrue(typeof(HashTableCache
<IReviewer
>).IsInstanceOfType(repos
.Cache
));
168 ComplexGenericConfiguration_GetReviewableRepostiory_ShouldResolveToDemoRepostiroyInsideLoggingRepositoryWithNoCaching
171 IWindsorContainer container
=
172 new WindsorContainer(new XmlInterpreter(GetFilePath("ComplexGenericConfig.xml")));
173 IRepository
<IReviewableEmployee
> empRepost
= container
.Resolve
<IRepository
<IReviewableEmployee
>>();
174 Assert
.IsNotNull(empRepost
);
175 Assert
.IsTrue(typeof(LoggingRepositoryDecorator
<IReviewableEmployee
>).IsInstanceOfType(empRepost
));
176 LoggingRepositoryDecorator
<IReviewableEmployee
> log
=
177 empRepost
as LoggingRepositoryDecorator
<IReviewableEmployee
>;
178 IRepository
<IReviewableEmployee
> inner
= log
.inner
;
179 Assert
.IsNotNull(inner
);
180 Assert
.IsTrue(typeof(DemoRepository
<IReviewableEmployee
>).IsInstanceOfType(inner
));
181 DemoRepository
<IReviewableEmployee
> demoEmpRepost
= inner
as DemoRepository
<IReviewableEmployee
>;
182 Assert
.AreEqual("Generic Repostiory With No Cache", demoEmpRepost
.Name
);
183 Assert
.IsNotNull(demoEmpRepost
.Cache
);
184 Assert
.IsTrue(typeof(NullCache
<IReviewableEmployee
>).IsInstanceOfType(demoEmpRepost
.Cache
));
188 public void TestGenericSpecialization()
190 IWindsorContainer container
=
191 new WindsorContainer(new XmlInterpreter(GetFilePath("ComplexGenericConfig.xml")));
192 IRepository
<IReviewer
> repository
= container
.Resolve
<IRepository
<IReviewer
>>();
193 Assert
.IsTrue(typeof(ReviewerRepository
).IsInstanceOfType(repository
), "Not ReviewerRepository!");
197 public void ComplexGenericConfiguration_GetRepositoryByIdAndType()
199 IWindsorContainer container
=
200 new WindsorContainer(new XmlInterpreter(GetFilePath("ComplexGenericConfig.xml")));
201 IRepository
<IReviewer
> repository
= container
.Resolve
<IRepository
<IReviewer
>>("generic.repository");
202 Assert
.IsTrue(typeof(DemoRepository
<IReviewer
>).IsInstanceOfType(repository
), "Not DemoRepository!");
206 public void TestComponentLifestylePerGenericType()
208 IWindsorContainer container
= new WindsorContainer();
210 container
.AddComponent("comp", typeof(IRepository
<>), typeof(TransientRepository
<>));
212 object o1
= container
.Resolve
<IRepository
<Employee
>>();
213 object o2
= container
.Resolve
<IRepository
<Employee
>>();
214 object o3
= container
.Resolve
<IRepository
<Reviewer
>>();
215 object o4
= container
.Resolve
<IRepository
<Reviewer
>>();
217 Assert
.IsFalse(ReferenceEquals(o1
, o2
));
218 Assert
.IsFalse(ReferenceEquals(o1
, o3
));
219 Assert
.IsFalse(ReferenceEquals(o1
, o4
));
223 public void CanCreateANormalTypeWithCtorDependencyOnGenericType()
225 IWindsorContainer container
= new WindsorContainer();
227 container
.AddComponent("comp", typeof(NeedsGenericType
));
228 container
.AddComponent("cache", typeof(ICache
<>), typeof(NullCache
<>));
230 NeedsGenericType needsGenericType
= container
.Resolve
<NeedsGenericType
>();
232 Assert
.IsNotNull(needsGenericType
);
236 public void InterceptGeneric1()
238 WindsorContainer container
= new WindsorContainer();
240 container
.AddFacility("interceptor-facility", new MyInterceptorGreedyFacility());
241 container
.AddComponent("interceptor", typeof(StandardInterceptor
));
242 container
.AddComponent("key", typeof(IRepository
<Employee
>), typeof(DemoRepository
<Employee
>));
244 IRepository
<Employee
> store
= container
.Resolve
<IRepository
<Employee
>>();
246 Assert
.IsFalse(typeof(DemoRepository
<Employee
>).IsInstanceOfType(store
), "This should have been a proxy");
250 public void InterceptGeneric2()
252 WindsorContainer container
= new WindsorContainer();
254 container
.AddFacility("interceptor-facility", new MyInterceptorGreedyFacility2());
255 container
.AddComponent("interceptor", typeof(StandardInterceptor
));
256 container
.AddComponent("key", typeof(IRepository
<>), typeof(DemoRepository
<>));
258 IRepository
<Employee
> store
= container
.Resolve
<IRepository
<Employee
>>();
260 Assert
.IsFalse(typeof(DemoRepository
<Employee
>).IsInstanceOfType(store
), "This should have been a proxy");
264 public void ChainOfResponsability()
266 IWindsorContainer container
=
267 new WindsorContainer(new XmlInterpreter(GetFilePath("chainOfRespnsability.config")));
268 IResultFinder
<int> resolve
= container
.Resolve
<IResultFinder
<int>>();
269 Assert
.IsTrue(resolve
.Finder
is DatabaseResultFinder
<int>);
270 Assert
.IsTrue(resolve
.Finder
.Finder
is WebServiceResultFinder
<int>);
271 Assert
.IsTrue(resolve
.Finder
.Finder
.Finder
is FailedResultFinder
<int>);
272 Assert
.IsTrue(resolve
.Finder
.Finder
.Finder
.Finder
== null);
276 public void ChainOfResponsability_Smart()
278 IWindsorContainer container
=
279 new WindsorContainer(new XmlInterpreter(GetFilePath("chainOfRespnsability_smart.config")));
280 IResultFinder
<int> resolve
= container
.Resolve
<IResultFinder
<int>>();
281 Assert
.IsTrue(resolve
is CacheResultFinder
<int>);
282 Assert
.IsTrue(resolve
.Finder
is DatabaseResultFinder
<int>);
283 Assert
.IsTrue(resolve
.Finder
.Finder
is WebServiceResultFinder
<int>);
284 Assert
.IsNull(resolve
.Finder
.Finder
.Finder
);
286 IResultFinder
<String
> resolve2
= container
.Resolve
<IResultFinder
<String
>>();
287 Assert
.IsTrue(resolve2
is ResultFinderStringDecorator
);
288 Assert
.IsNotNull(resolve2
.Finder
);
292 public void LifestyleIsInheritsFromGenericType()
294 WindsorContainer container
= new WindsorContainer();
296 container
.AddFacility("interceptor-facility", new MyInterceptorGreedyFacility2());
297 container
.AddComponent("interceptor", typeof(StandardInterceptor
));
298 container
.AddComponentLifeStyle("key", typeof(IRepository
<>), typeof(DemoRepository
<>), LifestyleType
.Transient
);
300 IRepository
<Employee
> store
= container
.Resolve
<IRepository
<Employee
>>();
301 IRepository
<Employee
> anotherStore
= container
.Resolve
<IRepository
<Employee
>>();
303 Assert
.IsFalse(typeof(DemoRepository
<Employee
>).IsInstanceOfType(store
), "This should have been a proxy");
304 Assert
.AreNotSame(store
, anotherStore
, "This should be two different instances");
308 public void InterceptorInheritFromGenericType()
310 WindsorContainer container
= new WindsorContainer();
312 container
.AddComponent("interceptor", typeof(MyInterceptor
));
313 container
.AddComponent("key", typeof(IRepository
<>), typeof(DemoRepository
<>));
314 container
.Kernel
.GetHandler(typeof(IRepository
<>)).ComponentModel
.Interceptors
.Add(
315 new InterceptorReference(typeof(MyInterceptor
)));
317 IRepository
<object> demoRepository
= container
.Resolve
<IRepository
<object>>();
318 demoRepository
.Get(12);
320 Assert
.AreEqual(12, MyInterceptor
.InterceptedId
, "invocation should have been intercepted by MyInterceptor");
324 public void ParentResolverIntercetorShouldNotAffectGenericComponentInterceptor()
326 WindsorContainer container
= new WindsorContainer();
327 container
.AddComponent
<MyInterceptor
>();
330 Component
.For
<ISpecification
>()
331 .ImplementedBy
<MySpecification
>()
332 .Interceptors(new InterceptorReference(typeof(MyInterceptor
)))
335 container
.AddComponent("repos", typeof(IRepository
<>), typeof(TransientRepository
<>));
337 ISpecification specification
= container
.Resolve
<ISpecification
>();
338 bool isProxy
= specification
.Repository
.GetType().FullName
.Contains("Proxy");
339 Assert
.IsFalse(isProxy
);
342 public string GetFilePath(string fileName
)
344 return Path
.Combine(AppDomain
.CurrentDomain
.BaseDirectory
,
345 ConfigHelper
.ResolveConfigPath("DotNet2Config/" + fileName
));
349 public class MyInterceptor
: IInterceptor
351 public static int InterceptedId
= 0;
353 public void Intercept(IInvocation invocation
)
355 invocation
.Proceed();
356 if (invocation
.Arguments
.Length
> 0)
357 InterceptedId
= (int)invocation
.Arguments
[0];
361 public interface IResultFinder
<T
>
363 T
Process(ISpecification specification
);
364 IResultFinder
<T
> Finder { get; }
367 public class CacheResultFinder
<T
> : IResultFinder
<T
>
369 private IResultFinder
<T
> finder
;
371 public IResultFinder
<T
> Finder
373 get { return finder; }
376 public CacheResultFinder()
380 public CacheResultFinder(IResultFinder
<T
> finder
)
382 this.finder
= finder
;
385 public T
Process(ISpecification specification
)
391 public class DatabaseResultFinder
<T
> : IResultFinder
<T
>
393 private IResultFinder
<T
> finder
;
395 public IResultFinder
<T
> Finder
397 get { return finder; }
400 public DatabaseResultFinder()
404 public DatabaseResultFinder(IResultFinder
<T
> finder
)
406 this.finder
= finder
;
409 public T
Process(ISpecification specification
)
415 public class WebServiceResultFinder
<T
> : IResultFinder
<T
>
417 private IResultFinder
<T
> finder
;
419 public IResultFinder
<T
> Finder
421 get { return finder; }
424 public WebServiceResultFinder()
428 public WebServiceResultFinder(IResultFinder
<T
> finder
)
430 this.finder
= finder
;
433 public T
Process(ISpecification specification
)
439 public class FailedResultFinder
<T
> : IResultFinder
<T
>
441 public IResultFinder
<T
> Finder
446 public T
Process(ISpecification specification
)
452 public class ResultFinderStringDecorator
: IResultFinder
<string>
454 private IResultFinder
<string> finder
;
456 public ResultFinderStringDecorator(IResultFinder
<string> finder
)
458 this.finder
= finder
;
461 public IResultFinder
<string> Finder
463 get { return finder; }
466 public String
Process(ISpecification specification
)
472 public interface ISpecification
474 IRepository
<int> Repository { get; }
477 public class MySpecification
: ISpecification
479 private readonly IRepository
<int> repository
;
481 public IRepository
<int> Repository
483 get { return repository; }
486 public MySpecification(IRepository
<int> repository
)
488 this.repository
= repository
;