Index: Rhino.Commons.Test/Binsor/BinsorStreamTestCase.cs =================================================================== --- Rhino.Commons.Test/Binsor/BinsorStreamTestCase.cs (revision 0) +++ Rhino.Commons.Test/Binsor/BinsorStreamTestCase.cs (revision 0) @@ -0,0 +1,158 @@ +using System; +using System.IO; +using Castle.Core; +using Castle.Core.Configuration; +using Castle.MicroKernel; +using Castle.Windsor; +using MbUnit.Framework; +using Rhino.Commons.Binsor; +using Rhino.Commons.Test.Components; +using System.Resources; + +namespace Rhino.Commons.Test.Binsor +{ + [TestFixture] + public class BinsorStreamTestCase + { + private IWindsorContainer _container; + [SetUp] + public void TestInitialize() + { + _container = new RhinoContainer(); + + Stream stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("Rhino.Commons.Test.Binsor.EmbeddedWindsor.boo"); + + BooReader.Read(_container, stream, "EmbdeddedWindsor"); + } + + [Test] + public void CanReadComponentFromConfiguration() + { + bool has_repos = _container.Kernel.HasComponent(typeof(IRepository<>)); + Assert.IsTrue(has_repos, "should have generic repository!"); + } + + [Test] + public void CanUseSpecilaizedGenerics() + { + IRepository resolve = _container.Resolve>(); + bool is_instance_of_fake = typeof(FakeRepository).IsInstanceOfType(resolve); + Assert.IsTrue(is_instance_of_fake); + } + + [Test] + public void CanPassComponentReferences() + { + FakeRepository fakeRepository = (FakeRepository)_container.Resolve>(); + + Assert.IsNotNull(fakeRepository.Inner); + Assert.IsTrue(fakeRepository.Inner is NHRepository); + + } + + [Test] + public void CanPassPrimitiveParameters() + { + EmailSender sender = _container.Resolve() as EmailSender; + Assert.AreEqual("example.dot.org", sender.Host); + } + + [Test] + public void CanUseLoops() + { + Fubar foo1 = (Fubar)_container.Resolve("foo_1"); + Assert.IsNotNull(foo1); + Assert.AreEqual(1, foo1.Foo); + Fubar foo2 = (Fubar)_container.Resolve("foo_2"); + Assert.IsNotNull(foo2); + Assert.AreEqual(2, foo2.Foo); + Fubar foo3 = (Fubar)_container.Resolve("foo_3"); + Assert.IsNotNull(foo3); + Assert.AreEqual(3, foo3.Foo); + } + + [Test] + public void CanSpecifyLifeStyle() + { + IHandler handler = _container.Kernel.GetHandler("defualt_repository"); + Assert.AreEqual(LifestyleType.Transient, handler.ComponentModel.LifestyleType); + } + + [Test] + public void ContainerUsesXmlConfigurationIfNotBooExtension() + { + RhinoContainer container = new RhinoContainer( + Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"..\..\Binsor\Windsor.xml")); + + ISender sender = container.Resolve(); + Assert.IsNotNull(sender); + } + + [Test] + public void CanDefineConfiguration() + { + IHandler handler = _container.Kernel.GetHandler("email_sender2"); + Assert.IsNotNull(handler); + + IConfiguration component = handler.ComponentModel.Configuration; + Assert.AreEqual("component", component.Name); + Assert.AreEqual("true", component.Attributes["startable"]); + + IConfiguration parameters = AssertConfiguration(component, "parameters"); + IConfiguration to = AssertConfiguration(parameters, "to"); + Assert.AreEqual(2, to.Children.Count); + Assert.AreEqual("craig", to.Children[0].Value); + Assert.AreEqual("ayende", to.Children[1].Value); + + IConfiguration backups = AssertConfiguration(parameters, "backups"); + Assert.AreEqual(2, backups.Children.Count); + Assert.AreEqual("${email_sender}", backups.Children[0].Value); + Assert.AreEqual("${email_sender}", backups.Children[1].Value); + } + + [Test] + public void CanDefineComplexConfigurations() + { + IHandler handler = _container.Kernel.GetHandler("fubar1"); + Assert.IsNotNull(handler); + + IConfiguration component = handler.ComponentModel.Configuration; + IConfiguration parameters = AssertConfiguration(component, "parameters"); + IConfiguration fields = AssertConfiguration(parameters, "fields"); + IConfiguration map = AssertConfiguration(fields, "map"); + Assert.AreEqual(2, map.Children.Count); + IConfiguration item1 = map.Children[0]; + Assert.AreEqual("name", item1.Attributes["key"]); + Assert.AreEqual("David Beckham", item1.Value); + IConfiguration item2 = map.Children[1]; + Assert.AreEqual("age", item2.Attributes["key"]); + Assert.AreEqual("32", item2.Value); + } + + [Test] + public void CanDefineComplexConfigurationsWithBuilders() + { + IHandler handler = _container.Kernel.GetHandler("fubar2"); + Assert.IsNotNull(handler); + + IConfiguration component = handler.ComponentModel.Configuration; + IConfiguration parameters = AssertConfiguration(component, "parameters"); + IConfiguration fields = AssertConfiguration(parameters, "fields"); + IConfiguration map = AssertConfiguration(fields, "map"); + Assert.AreEqual(2, map.Children.Count); + IConfiguration item1 = map.Children[0]; + Assert.AreEqual("name", item1.Attributes["name"]); + Assert.AreEqual("David Beckham", item1.Value); + IConfiguration item2 = map.Children[1]; + Assert.AreEqual("age", item2.Attributes["name"]); + Assert.AreEqual("32", item2.Value); + } + + private static IConfiguration AssertConfiguration(IConfiguration parent, string name) + { + IConfiguration config = parent.Children[name]; + Assert.IsNotNull(config); + return config; + } + } +} Index: Rhino.Commons.Test/Binsor/EmbeddedWindsor.boo =================================================================== --- Rhino.Commons.Test/Binsor/EmbeddedWindsor.boo (revision 0) +++ Rhino.Commons.Test/Binsor/EmbeddedWindsor.boo (revision 0) @@ -0,0 +1,87 @@ +#region license +// Copyright (c) 2005 - 2007 Ayende Rahien (ayende@ayende.com) +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Ayende Rahien nor the names of its +// contributors may be used to endorse or promote products derived from this +// software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#endregion + +import Rhino.Commons +import Rhino.Commons.Test.Components from Rhino.Commons.Test +import Rhino.Commons.Test.Binsor +import Castle.Facilities.Logging +# Facility constructors + +Facility("loggerFacility", LoggingFacility, + loggingApi: LoggerImplementation.Log4net, + configFile: "log4net.config" + ) + +# generic type registration +Component(defualt_repository, IRepository, NHRepository, LifestyleType.Transient) + +customer_repository = Component("customer_repository", + IRepository of Fubar, FakeRepository of Fubar, + inner: @defualt_repository) + + +email = Component("email_sender", ISender, EmailSender, + Host: "example.dot.org") + +Component("email_sender2", ISender, EmailSender, + { @startable: true, + parameters: { + to: ( "craig", "ayende" ), + backups: ( @email_sender, email ) + } + } ) + +# making sure that loops work + +for i in range(4): + o = Component("foo_${i}", Fubar) + o.foo = i + +Component("fubar1", Fubar, + { @factoryId: 'fubar_factory', + @factoryCreate: 'Create', + parameters: { + fields: { + keymap(fields): { + name: 'David Beckham', + age: 32 + } + } + } } + ) + +Component("fubar2", Fubar, + { @factoryId: 'fubar_factory', + @factoryCreate: 'Create', + parameters: { + keyvalues(fields): { + name: 'David Beckham', + age: 32 + } + } } + ) \ No newline at end of file Index: Rhino.Commons.Test/Rhino.Commons.Test.csproj =================================================================== --- Rhino.Commons.Test/Rhino.Commons.Test.csproj (revision 887) +++ Rhino.Commons.Test/Rhino.Commons.Test.csproj (working copy) @@ -133,6 +133,7 @@ + @@ -164,6 +165,7 @@ + @@ -202,4 +204,4 @@ --> - \ No newline at end of file + Index: Rhino.Commons/Binsor/BooReader.cs =================================================================== --- Rhino.Commons/Binsor/BooReader.cs (revision 887) +++ Rhino.Commons/Binsor/BooReader.cs (working copy) @@ -89,6 +89,32 @@ } } + public static void Read(IWindsorContainer container, Stream stream, string name) + { + Read(container, stream, GenerationOptions.Memory, name); + } + + public static void Read(IWindsorContainer container, Stream stream, GenerationOptions generationOptions, string name) + { + try + { + using (IoC.UseLocalContainer(container)) + { + IConfigurationRunner conf = GetConfigurationInstanceFromStream(name, stream, generationOptions); + conf.Run(); + foreach (INeedSecondPassRegistration needSecondPassRegistration in NeedSecondPassRegistrations) + { + needSecondPassRegistration.RegisterSecondPass(); + } + } + } + finally + { + NeedSecondPassRegistrations = null; + } + } + + private static IConfigurationRunner GetConfigurationInstanceFromFile(string fileName, GenerationOptions generationOptions) { FileInput fileInput = new FileInput(fileName); @@ -116,6 +142,33 @@ Type type = run.GeneratedAssembly.GetType(Path.GetFileNameWithoutExtension(fileName)); return Activator.CreateInstance(type) as IConfigurationRunner; } + private static IConfigurationRunner GetConfigurationInstanceFromStream(string name, Stream stream, GenerationOptions generationOptions) + { + ReaderInput readerInput = new ReaderInput(name, new StreamReader(stream)); + BooCompiler compiler = new BooCompiler(); + compiler.Parameters.Ducky = true; + if (generationOptions == GenerationOptions.Memory) + compiler.Parameters.Pipeline = new CompileToMemory(); + else + compiler.Parameters.Pipeline = new CompileToFile(); + + compiler.Parameters.Pipeline.Insert(1, new BinsorCompilerStep()); + compiler.Parameters.Pipeline.Replace( + typeof(ProcessMethodBodiesWithDuckTyping), + new TransformUnknownReferences()); + compiler.Parameters.Pipeline.InsertAfter(typeof(TransformUnknownReferences), + new RegisterComponentAndFacilitiesAfterCreation()); + compiler.Parameters.OutputType = CompilerOutputType.Library; + compiler.Parameters.Input.Add(readerInput); + compiler.Parameters.References.Add(typeof(BooReader).Assembly); + CompilerContext run = compiler.Run(); + if (run.Errors.Count != 0) + { + throw new CompilerError(string.Format("Could not compile configuration! {0}", run.Errors.ToString(true))); + } + Type type = run.GeneratedAssembly.GetType(name); + return Activator.CreateInstance(type) as IConfigurationRunner; + } public enum GenerationOptions {