You can subscribe to this list here.
2006 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
(1) |
Oct
|
Nov
|
Dec
|
---|---|---|---|---|---|---|---|---|---|---|---|---|
2007 |
Jan
|
Feb
(5) |
Mar
(9) |
Apr
(9) |
May
(4) |
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(3) |
2008 |
Jan
(11) |
Feb
(6) |
Mar
|
Apr
(16) |
May
(28) |
Jun
(13) |
Jul
(3) |
Aug
(19) |
Sep
(11) |
Oct
(37) |
Nov
(1) |
Dec
(17) |
2009 |
Jan
(16) |
Feb
(6) |
Mar
|
Apr
(6) |
May
(1) |
Jun
(10) |
Jul
(4) |
Aug
(4) |
Sep
(4) |
Oct
(8) |
Nov
(3) |
Dec
(45) |
2010 |
Jan
(8) |
Feb
(21) |
Mar
(2) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2016 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(1) |
Sep
(1) |
Oct
|
Nov
|
Dec
|
From: <fli...@us...> - 2008-12-19 05:04:55
|
Revision: 200 http://structuremap.svn.sourceforge.net/structuremap/?rev=200&view=rev Author: flimflan Date: 2008-12-19 05:04:53 +0000 (Fri, 19 Dec 2008) Log Message: ----------- Added AutoMocking support for Moq Modified Paths: -------------- trunk/Source/StructureMap.AutoMocking/RhinoAutoMocker.cs trunk/Source/StructureMap.AutoMocking/ServiceLocator.cs trunk/Source/StructureMap.AutoMocking/StructureMap.AutoMocking.csproj trunk/Source/StructureMap.Testing/AutoMocking/RhinoAutoMockerTester.cs trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj Added Paths: ----------- trunk/Source/StructureMap.AutoMocking/MoqAutoMocker.cs trunk/Source/StructureMap.AutoMocking/MoqFactory.cs trunk/Source/StructureMap.Testing/AutoMocking/AutoMockerTester.cs trunk/Source/StructureMap.Testing/AutoMocking/MoqAutoMockerTester.cs trunk/Source/StructureMap.Testing/AutoMocking/MoqFactoryTester.cs trunk/bin/Moq.dll Property Changed: ---------------- trunk/ Property changes on: trunk ___________________________________________________________________ Modified: svn:ignore - build results push.bat + build results push.bat deploy TestResult.xml Copied: trunk/Source/StructureMap.AutoMocking/MoqAutoMocker.cs (from rev 199, trunk/Source/StructureMap.AutoMocking/RhinoAutoMocker.cs) =================================================================== --- trunk/Source/StructureMap.AutoMocking/MoqAutoMocker.cs (rev 0) +++ trunk/Source/StructureMap.AutoMocking/MoqAutoMocker.cs 2008-12-19 05:04:53 UTC (rev 200) @@ -0,0 +1,15 @@ +namespace StructureMap.AutoMocking +{ + /// <summary> + /// Provides an "Auto Mocking Container" for the concrete class TARGETCLASS using Moq + /// </summary> + /// <typeparam name="TARGETCLASS">The concrete class being tested</typeparam> + public class MoqAutoMocker<TARGETCLASS> : AutoMocker<TARGETCLASS> where TARGETCLASS : class + { + public MoqAutoMocker() + { + _serviceLocator = new MoqServiceLocator(); + _container = new AutoMockedContainer(_serviceLocator); + } + } +} \ No newline at end of file Property changes on: trunk/Source/StructureMap.AutoMocking/MoqAutoMocker.cs ___________________________________________________________________ Added: svn:mergeinfo + Copied: trunk/Source/StructureMap.AutoMocking/MoqFactory.cs (from rev 199, trunk/Source/StructureMap.AutoMocking/RhinoMockRepositoryProxy.cs) =================================================================== --- trunk/Source/StructureMap.AutoMocking/MoqFactory.cs (rev 0) +++ trunk/Source/StructureMap.AutoMocking/MoqFactory.cs 2008-12-19 05:04:53 UTC (rev 200) @@ -0,0 +1,36 @@ +using System; +using System.Reflection; + +namespace StructureMap.AutoMocking +{ + public class MoqFactory + { + private readonly Type mockOpenType; + + public MoqFactory() + { + var Moq = Assembly.Load("Moq"); + mockOpenType = Moq.GetType("Moq.Mock`1"); + if (mockOpenType == null) throw new InvalidOperationException("Unable to find Type Moq.Mock<T> in assembly " + Moq.Location); + } + + public object CreateMock(Type type) + { + var closedType = mockOpenType.MakeGenericType(new[] {type}); + var objectProperty = closedType.GetProperty("Object", type); + var instance = Activator.CreateInstance(closedType); + return objectProperty.GetValue(instance, null); + } + + public object CreateMockThatCallsBase(Type type, object[] args) + { + var closedType = mockOpenType.MakeGenericType(new[] { type }); + var callBaseProperty = closedType.GetProperty("CallBase", typeof(bool)); + var objectProperty = closedType.GetProperty("Object", type); + var constructor = closedType.GetConstructor(new[]{typeof(object[])}); + var instance = constructor.Invoke(new[]{args}); + callBaseProperty.SetValue(instance, true, null); + return objectProperty.GetValue(instance, null); + } + } +} \ No newline at end of file Property changes on: trunk/Source/StructureMap.AutoMocking/MoqFactory.cs ___________________________________________________________________ Added: svn:mergeinfo + Modified: trunk/Source/StructureMap.AutoMocking/RhinoAutoMocker.cs =================================================================== --- trunk/Source/StructureMap.AutoMocking/RhinoAutoMocker.cs 2008-12-19 02:41:25 UTC (rev 199) +++ trunk/Source/StructureMap.AutoMocking/RhinoAutoMocker.cs 2008-12-19 05:04:53 UTC (rev 200) @@ -9,7 +9,7 @@ public enum MockMode { RecordAndReplay, AAA } /// <summary> - /// Provides an "Auto Mocking Container" for the concrete class TARGETCLASS + /// Provides an "Auto Mocking Container" for the concrete class TARGETCLASS using Rhino.Mocks /// </summary> /// <typeparam name="TARGETCLASS">The concrete class being tested</typeparam> public class RhinoAutoMocker<TARGETCLASS> : AutoMocker<TARGETCLASS> where TARGETCLASS : class Modified: trunk/Source/StructureMap.AutoMocking/ServiceLocator.cs =================================================================== --- trunk/Source/StructureMap.AutoMocking/ServiceLocator.cs 2008-12-19 02:41:25 UTC (rev 199) +++ trunk/Source/StructureMap.AutoMocking/ServiceLocator.cs 2008-12-19 05:04:53 UTC (rev 200) @@ -54,4 +54,24 @@ return instance; } } + + public class MoqServiceLocator : ServiceLocator + { + private readonly MoqFactory _moqs = new MoqFactory(); + + public T Service<T>() where T : class + { + return (T)_moqs.CreateMock(typeof(T)); + } + + public object Service(Type serviceType) + { + return _moqs.CreateMock(serviceType); + } + + public T PartialMock<T>(params object[] args) where T : class + { + return (T)_moqs.CreateMockThatCallsBase(typeof (T), args); + } + } } \ No newline at end of file Modified: trunk/Source/StructureMap.AutoMocking/StructureMap.AutoMocking.csproj =================================================================== --- trunk/Source/StructureMap.AutoMocking/StructureMap.AutoMocking.csproj 2008-12-19 02:41:25 UTC (rev 199) +++ trunk/Source/StructureMap.AutoMocking/StructureMap.AutoMocking.csproj 2008-12-19 05:04:53 UTC (rev 200) @@ -2,7 +2,7 @@ <PropertyGroup> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> - <ProductVersion>9.0.21022</ProductVersion> + <ProductVersion>9.0.30729</ProductVersion> <SchemaVersion>2.0</SchemaVersion> <ProjectGuid>{0ED1B206-A1C9-4A52-BA87-3BA416C8725C}</ProjectGuid> <OutputType>Library</OutputType> @@ -66,6 +66,8 @@ </Compile> <Compile Include="AutoMockedContainer.cs" /> <Compile Include="AutoMocker.cs" /> + <Compile Include="MoqAutoMocker.cs" /> + <Compile Include="MoqFactory.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="RhinoAutoMocker.cs" /> <Compile Include="RhinoMockRepositoryProxy.cs" /> @@ -107,4 +109,4 @@ <Target Name="AfterBuild"> </Target> --> -</Project> +</Project> \ No newline at end of file Copied: trunk/Source/StructureMap.Testing/AutoMocking/AutoMockerTester.cs (from rev 197, trunk/Source/StructureMap.Testing/AutoMocking/RhinoAutoMockerTester.cs) =================================================================== --- trunk/Source/StructureMap.Testing/AutoMocking/AutoMockerTester.cs (rev 0) +++ trunk/Source/StructureMap.Testing/AutoMocking/AutoMockerTester.cs 2008-12-19 05:04:53 UTC (rev 200) @@ -0,0 +1,267 @@ +using System; +using System.Linq.Expressions; +using NUnit.Framework; +using StructureMap.AutoMocking; + +namespace StructureMap.Testing.AutoMocking +{ + [TestFixture] + public abstract class AutoMockerTester + { + protected abstract AutoMocker<T> createAutoMocker<T>() where T : class; + protected abstract void setExpectation<T, TResult>(T mock, Expression<Func<T, TResult>> functionCall, TResult expectedResult) where T : class; + + public class ConcreteThing + { + private readonly IMockedService _service; + private readonly IMockedService2 _service2; + + + public ConcreteThing(IMockedService service, IMockedService2 service2) + { + _service = service; + _service2 = service2; + } + + + public IMockedService Service + { + get { return _service; } + } + + public IMockedService2 Service2 + { + get { return _service2; } + } + } + + public class ConcreteClass + { + private readonly IMockedService _service; + private readonly IMockedService2 _service2; + private readonly IMockedService3 _service3; + + public ConcreteClass(IMockedService service, IMockedService2 service2, IMockedService3 service3) + { + _service = service; + _service2 = service2; + _service3 = service3; + } + + public virtual string Name + { + get { return _service.Name; } + } + + public IMockedService Service + { + get { return _service; } + } + + public IMockedService2 Service2 + { + get { return _service2; } + } + + public IMockedService3 Service3 + { + get { return _service3; } + } + + public void CallService() + { + _service.Go(); + } + } + + public interface IMockedService + { + string Name { get; } + void Go(); + } + + public interface IMockedService2 + { + void Go(); + } + + public interface IMockedService3 + { + void Go(); + } + + + public class StubService : IMockedService + { + private readonly string _name; + + public StubService() + { + } + + public StubService(string name) + { + _name = name; + } + + #region IMockedService Members + + public string Name + { + get { return _name; } + } + + public void Go() + { + throw new NotImplementedException(); + } + + #endregion + } + + public class ClassWithArray + { + private readonly IMockedService[] _services; + + public ClassWithArray(IMockedService[] services) + { + _services = services; + } + + public IMockedService[] Services + { + get { return _services; } + } + } + + [Test] + public void CanInjectAnArrayOfMockServices1() + { + var mocker = createAutoMocker<ClassWithArray>(); + + IMockedService[] services = mocker.CreateMockArrayFor<IMockedService>(3); + ClassWithArray theClass = mocker.ClassUnderTest; + + theClass.Services.Length.ShouldEqual(3); + } + + [Test] + public void CanInjectAnArrayOfMockServices2() + { + var mocker = createAutoMocker<ClassWithArray>(); + + ClassWithArray theClass = mocker.ClassUnderTest; + + theClass.Services.Length.ShouldEqual(0); + } + + + [Test] + public void CanInjectAnArrayOfMockServices3() + { + var mocker = createAutoMocker<ClassWithArray>(); + + IMockedService[] services = mocker.CreateMockArrayFor<IMockedService>(3); + + mocker.PartialMockTheClassUnderTest(); + ClassWithArray theClass = mocker.ClassUnderTest; + + theClass.Services.Length.ShouldEqual(3); + } + + [Test] + public void CanInjectAnArrayOfMockServices4() + { + var mocker = createAutoMocker<ClassWithArray>(); + + mocker.PartialMockTheClassUnderTest(); + ClassWithArray theClass = mocker.ClassUnderTest; + + theClass.Services.Length.ShouldEqual(0); + } + + + [Test] + public void GetTheSameConcreteClassTwiceFromCreate() + { + var autoMocker = createAutoMocker<ConcreteClass>(); + ConcreteClass concreteClass = autoMocker.ClassUnderTest; + + Assert.AreSame(concreteClass, autoMocker.ClassUnderTest); + Assert.AreSame(concreteClass, autoMocker.ClassUnderTest); + Assert.AreSame(concreteClass, autoMocker.ClassUnderTest); + } + + [Test] + public void TheAutoMockerPushesInMocksAndAPreBuiltStubForAllOfTheConstructorArguments() + { + var autoMocker = createAutoMocker<ConcreteClass>(); + var stub = new StubService(); + autoMocker.Inject<IMockedService>(stub); + + var service2 = autoMocker.Get<IMockedService2>(); + var service3 = autoMocker.Get<IMockedService3>(); + + ConcreteClass concreteClass = autoMocker.ClassUnderTest; + + Assert.AreSame(stub, concreteClass.Service); + Assert.AreSame(service2, concreteClass.Service2); + Assert.AreSame(service3, concreteClass.Service3); + } + + [Test] + public void TheAutoMockerPushesInMocksForAllOfTheConstructorArgumentsForAPartialMock() + { + var autoMocker = createAutoMocker<ConcreteClass>(); + + var service = autoMocker.Get<IMockedService>(); + var service2 = autoMocker.Get<IMockedService2>(); + var service3 = autoMocker.Get<IMockedService3>(); + + autoMocker.PartialMockTheClassUnderTest(); + ConcreteClass concreteClass = autoMocker.ClassUnderTest; + + Assert.AreSame(service, concreteClass.Service); + Assert.AreSame(service2, concreteClass.Service2); + Assert.AreSame(service3, concreteClass.Service3); + } + + [Test] + public void UseConcreteClassFor() + { + var mocker = createAutoMocker<ConcreteClass>(); + mocker.UseConcreteClassFor<ConcreteThing>(); + + var thing = mocker.Get<ConcreteThing>(); + Assert.IsInstanceOfType(typeof (ConcreteThing), thing); + + Assert.AreSame(mocker.Get<IMockedService>(), thing.Service); + Assert.AreSame(mocker.Get<IMockedService2>(), thing.Service2); + } + + [Test] + public void UseTheAutoMockerToStartUpTheConcreteClass() + { + var autoMocker = createAutoMocker<ConcreteClass>(); + setExpectation(autoMocker.Get<IMockedService>(), x=> x.Name, "Jeremy"); + autoMocker.ClassUnderTest.Name.ShouldEqual("Jeremy"); + } + + [Test] + public void UseTheAutoMockerToStartUpTheConcreteClassAsAPartialMockAndSetTheNameMethodUp() + { + var autoMocker = createAutoMocker<ConcreteClass>(); + + autoMocker.PartialMockTheClassUnderTest(); + ConcreteClass concreteClass = autoMocker.ClassUnderTest; + setExpectation(concreteClass, x=> x.Name, "Max"); + concreteClass.Name.ShouldEqual("Max"); + } + + public interface IAnotherService + { + + } + + } +} \ No newline at end of file Property changes on: trunk/Source/StructureMap.Testing/AutoMocking/AutoMockerTester.cs ___________________________________________________________________ Added: svn:mergeinfo + Added: trunk/Source/StructureMap.Testing/AutoMocking/MoqAutoMockerTester.cs =================================================================== --- trunk/Source/StructureMap.Testing/AutoMocking/MoqAutoMockerTester.cs (rev 0) +++ trunk/Source/StructureMap.Testing/AutoMocking/MoqAutoMockerTester.cs 2008-12-19 05:04:53 UTC (rev 200) @@ -0,0 +1,22 @@ +using System; +using Moq; +using NUnit.Framework; +using StructureMap.AutoMocking; +using System.Linq.Expressions; + +namespace StructureMap.Testing.AutoMocking +{ + [TestFixture] + public class MoqAutoMockerTester : AutoMockerTester + { + protected override AutoMocker<T> createAutoMocker<T>() + { + return new MoqAutoMocker<T>(); + } + + protected override void setExpectation<T, TResult>(T mock, Expression<Func<T, TResult>> functionCall, TResult expectedResult) + { + Mock.Get(mock).Expect(functionCall).Returns(expectedResult); + } + } +} Copied: trunk/Source/StructureMap.Testing/AutoMocking/MoqFactoryTester.cs (from rev 199, trunk/Source/StructureMap.Testing/AutoMocking/RhinoMockRepositoryProxyTester.cs) =================================================================== --- trunk/Source/StructureMap.Testing/AutoMocking/MoqFactoryTester.cs (rev 0) +++ trunk/Source/StructureMap.Testing/AutoMocking/MoqFactoryTester.cs 2008-12-19 05:04:53 UTC (rev 200) @@ -0,0 +1,46 @@ +using Moq; +using NUnit.Framework; +using StructureMap.AutoMocking; + +namespace StructureMap.Testing.AutoMocking +{ + [TestFixture] + public class MoqFactoryTester + { + + [Test] + public void sample_moq_usage() + { + var mock = new Mock<ITestMocks>(); + mock.Expect(t => t.Answer()).Returns("Moq"); + mock.Object.Answer().ShouldEqual("Moq"); + } + + [Test] + public void can_make_dynamic_mocks() + { + var moqFactory = new MoqFactory(); + var fooMock = moqFactory.CreateMock(typeof(ITestMocks)); + + fooMock.ShouldNotBeNull(); + } + + [Test] + public void can_make_partial_mocks() + { + var moqFactory = new MoqFactory(); + var testPartials = (TestPartials)moqFactory.CreateMockThatCallsBase(typeof(TestPartials), new object[0]); + + testPartials.ShouldNotBeNull(); + testPartials.Concrete().ShouldEqual("Concrete"); + testPartials.Virtual().ShouldEqual("Virtual"); + + var mock = Mock.Get(testPartials); + mock.Expect(t => t.Virtual()).Returns("MOQed!"); + testPartials.Virtual().ShouldEqual("MOQed!"); + } + + } + + +} \ No newline at end of file Property changes on: trunk/Source/StructureMap.Testing/AutoMocking/MoqFactoryTester.cs ___________________________________________________________________ Added: svn:mergeinfo + Modified: trunk/Source/StructureMap.Testing/AutoMocking/RhinoAutoMockerTester.cs =================================================================== --- trunk/Source/StructureMap.Testing/AutoMocking/RhinoAutoMockerTester.cs 2008-12-19 02:41:25 UTC (rev 199) +++ trunk/Source/StructureMap.Testing/AutoMocking/RhinoAutoMockerTester.cs 2008-12-19 05:04:53 UTC (rev 200) @@ -1,4 +1,5 @@ using System; +using System.Linq.Expressions; using NUnit.Framework; using Rhino.Mocks; using Rhino.Mocks.Interfaces; @@ -8,7 +9,7 @@ namespace StructureMap.Testing.AutoMocking { [TestFixture] - public class RhinoAutoMockerTester + public class RhinoAutoMockerTester : AutoMockerTester { #region Setup/Teardown @@ -26,130 +27,16 @@ private RhinoMocksAAAServiceLocator _locator; private AutoMockedContainer _container; - - public class ConcreteThing + protected override AutoMocker<T> createAutoMocker<T>() { - private readonly IMockedService _service; - private readonly IMockedService2 _service2; - - - public ConcreteThing(IMockedService service, IMockedService2 service2) - { - _service = service; - _service2 = service2; - } - - - public IMockedService Service - { - get { return _service; } - } - - public IMockedService2 Service2 - { - get { return _service2; } - } + return new RhinoAutoMocker<T>(); } - public class ConcreteClass + protected override void setExpectation<T,TResult>(T mock, Expression<Func<T,TResult>> functionCall, TResult expectedResult) { - private readonly IMockedService _service; - private readonly IMockedService2 _service2; - private readonly IMockedService3 _service3; - - public ConcreteClass(IMockedService service, IMockedService2 service2, IMockedService3 service3) - { - _service = service; - _service2 = service2; - _service3 = service3; - } - - public virtual string Name - { - get { return _service.Name; } - } - - public IMockedService Service - { - get { return _service; } - } - - public IMockedService2 Service2 - { - get { return _service2; } - } - - public IMockedService3 Service3 - { - get { return _service3; } - } - - public void CallService() - { - _service.Go(); - } + mock.Expect(x => functionCall.Compile()(mock)).Return(expectedResult); } - public interface IMockedService - { - string Name { get; } - void Go(); - } - - public interface IMockedService2 - { - void Go(); - } - - public interface IMockedService3 - { - void Go(); - } - - - public class StubService : IMockedService - { - private readonly string _name; - - public StubService() - { - } - - public StubService(string name) - { - _name = name; - } - - #region IMockedService Members - - public string Name - { - get { return _name; } - } - - public void Go() - { - throw new NotImplementedException(); - } - - #endregion - } - - public class ClassWithArray - { - private readonly IMockedService[] _services; - - public ClassWithArray(IMockedService[] services) - { - _services = services; - } - - public IMockedService[] Services - { - get { return _services; } - } - } - [Test] public void AutoFillAConcreteClassWithMocks() { @@ -164,54 +51,8 @@ Assert.AreSame(service3, concreteClass.Service3); } - [Test] - public void CanInjectAnArrayOfMockServices1() - { - var mocker = new RhinoAutoMocker<ClassWithArray>(); - IMockedService[] services = mocker.CreateMockArrayFor<IMockedService>(3); - ClassWithArray theClass = mocker.ClassUnderTest; - - theClass.Services.Length.ShouldEqual(3); - } - [Test] - public void CanInjectAnArrayOfMockServices2() - { - var mocker = new RhinoAutoMocker<ClassWithArray>(); - - ClassWithArray theClass = mocker.ClassUnderTest; - - theClass.Services.Length.ShouldEqual(0); - } - - - [Test] - public void CanInjectAnArrayOfMockServices3() - { - var mocker = new RhinoAutoMocker<ClassWithArray>(); - - IMockedService[] services = mocker.CreateMockArrayFor<IMockedService>(3); - - mocker.PartialMockTheClassUnderTest(); - ClassWithArray theClass = mocker.ClassUnderTest; - - theClass.Services.Length.ShouldEqual(3); - } - - [Test] - public void CanInjectAnArrayOfMockServices4() - { - var mocker = new RhinoAutoMocker<ClassWithArray>(); - - mocker.PartialMockTheClassUnderTest(); - ClassWithArray theClass = mocker.ClassUnderTest; - - theClass.Services.Length.ShouldEqual(0); - } - - - [Test] public void GetAFullMockForAServiceThatHasNotPreviouslyBeenRequested() { var service = _container.GetInstance<IMockedService>(); @@ -219,17 +60,6 @@ } [Test] - public void GetTheSameConcreteClassTwiceFromCreate() - { - var autoMocker = new RhinoAutoMocker<ConcreteClass>(); - ConcreteClass concreteClass = autoMocker.ClassUnderTest; - - Assert.AreSame(concreteClass, autoMocker.ClassUnderTest); - Assert.AreSame(concreteClass, autoMocker.ClassUnderTest); - Assert.AreSame(concreteClass, autoMocker.ClassUnderTest); - } - - [Test] public void InjectAStubAndGetTheStubBack() { var stub = new StubService(); @@ -250,76 +80,8 @@ Assert.AreSame(service, _container.GetInstance<IMockedService>()); } - [Test] - public void TheAutoMockerPushesInMocksAndAPreBuiltStubForAllOfTheConstructorArguments() - { - var autoMocker = new RhinoAutoMocker<ConcreteClass>(); - var stub = new StubService(); - autoMocker.Inject<IMockedService>(stub); - var service2 = autoMocker.Get<IMockedService2>(); - var service3 = autoMocker.Get<IMockedService3>(); - - ConcreteClass concreteClass = autoMocker.ClassUnderTest; - - Assert.AreSame(stub, concreteClass.Service); - Assert.AreSame(service2, concreteClass.Service2); - Assert.AreSame(service3, concreteClass.Service3); - } - [Test] - public void TheAutoMockerPushesInMocksForAllOfTheConstructorArgumentsForAPartialMock() - { - var autoMocker = new RhinoAutoMocker<ConcreteClass>(); - - var service = autoMocker.Get<IMockedService>(); - var service2 = autoMocker.Get<IMockedService2>(); - var service3 = autoMocker.Get<IMockedService3>(); - - autoMocker.PartialMockTheClassUnderTest(); - ConcreteClass concreteClass = autoMocker.ClassUnderTest; - - Assert.AreSame(service, concreteClass.Service); - Assert.AreSame(service2, concreteClass.Service2); - Assert.AreSame(service3, concreteClass.Service3); - } - - [Test] - public void UseConcreteClassFor() - { - var mocker = new RhinoAutoMocker<ConcreteClass>(); - mocker.UseConcreteClassFor<ConcreteThing>(); - - var thing = mocker.Get<ConcreteThing>(); - Assert.IsInstanceOfType(typeof (ConcreteThing), thing); - - Assert.AreSame(mocker.Get<IMockedService>(), thing.Service); - Assert.AreSame(mocker.Get<IMockedService2>(), thing.Service2); - } - - [Test] - public void UseTheAutoMockerToStartUpTheConcreteClass() - { - var autoMocker = new RhinoAutoMocker<ConcreteClass>(); - - autoMocker.Get<IMockedService>().Expect(x => x.Name).Return("Jeremy"); - - autoMocker.ClassUnderTest.Name.ShouldEqual("Jeremy"); - } - - [Test] - public void UseTheAutoMockerToStartUpTheConcreteClassAsAPartialMockAndSetTheNameMethodUp() - { - var autoMocker = new RhinoAutoMocker<ConcreteClass>(); - - autoMocker.PartialMockTheClassUnderTest(); - ConcreteClass concreteClass = autoMocker.ClassUnderTest; - - concreteClass.Expect(x => x.Name).Return("Max"); - concreteClass.Name.ShouldEqual("Max"); - } - - [Test] public void TheAutoMockerOptionallyPushesInMocksInReplayModeToAllowForAAAsyntax() { var autoMocker = new RhinoAutoMocker<ConcreteClass>(MockMode.AAA); Modified: trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj =================================================================== --- trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj 2008-12-19 02:41:25 UTC (rev 199) +++ trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj 2008-12-19 05:04:53 UTC (rev 200) @@ -1,7 +1,7 @@ <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5"> <PropertyGroup> <ProjectType>Local</ProjectType> - <ProductVersion>9.0.21022</ProductVersion> + <ProductVersion>9.0.30729</ProductVersion> <SchemaVersion>2.0</SchemaVersion> <ProjectGuid>{63C2742D-B6E2-484F-AFDB-346873075C5E}</ProjectGuid> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> @@ -91,6 +91,10 @@ <ErrorReport>prompt</ErrorReport> </PropertyGroup> <ItemGroup> + <Reference Include="Moq, Version=2.6.1014.1, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL"> + <SpecificVersion>False</SpecificVersion> + <HintPath>..\..\bin\Moq.dll</HintPath> + </Reference> <Reference Include="nunit.framework, Version=2.2.6.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77"> <SpecificVersion>False</SpecificVersion> <HintPath>..\..\bin\NUnit\nunit.framework.dll</HintPath> @@ -169,6 +173,9 @@ <Compile Include="Attributes\PluginFamilyAttributeTester.cs"> <SubType>Code</SubType> </Compile> + <Compile Include="AutoMocking\AutoMockerTester.cs" /> + <Compile Include="AutoMocking\MoqAutoMockerTester.cs" /> + <Compile Include="AutoMocking\MoqFactoryTester.cs" /> <Compile Include="AutoMocking\RhinoAutoMockerTester.cs" /> <Compile Include="AutoMocking\RhinoMockRepositoryProxyTester.cs" /> <Compile Include="BuildSessionTester.cs" /> @@ -446,4 +453,4 @@ <PostBuildEvent> </PostBuildEvent> </PropertyGroup> -</Project> +</Project> \ No newline at end of file Added: trunk/bin/Moq.dll =================================================================== (Binary files differ) Property changes on: trunk/bin/Moq.dll ___________________________________________________________________ Added: svn:mime-type + application/octet-stream This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fli...@us...> - 2008-12-19 02:41:31
|
Revision: 199 http://structuremap.svn.sourceforge.net/structuremap/?rev=199&view=rev Author: flimflan Date: 2008-12-19 02:41:25 +0000 (Fri, 19 Dec 2008) Log Message: ----------- Removed static reference to Rhino.Mocks.dll in AutoMocker - Allows Ayende to release as often as he wants, and we dont have to stay in synch - Allows MVBA to continue to live on the bleeding edge Modified Paths: -------------- trunk/Source/StructureMap.AutoMocking/RhinoAutoMocker.cs trunk/Source/StructureMap.AutoMocking/ServiceLocator.cs trunk/Source/StructureMap.AutoMocking/StructureMap.AutoMocking.csproj trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj Added Paths: ----------- trunk/Source/StructureMap.AutoMocking/RhinoMockRepositoryProxy.cs trunk/Source/StructureMap.Testing/AutoMocking/RhinoMockRepositoryProxyTester.cs Modified: trunk/Source/StructureMap.AutoMocking/RhinoAutoMocker.cs =================================================================== --- trunk/Source/StructureMap.AutoMocking/RhinoAutoMocker.cs 2008-12-17 16:41:58 UTC (rev 198) +++ trunk/Source/StructureMap.AutoMocking/RhinoAutoMocker.cs 2008-12-19 02:41:25 UTC (rev 199) @@ -1,9 +1,4 @@ using System; -using System.Collections; -using System.Collections.Generic; -using System.Reflection; -using Rhino.Mocks; -using StructureMap.Graph; namespace StructureMap.AutoMocking { Added: trunk/Source/StructureMap.AutoMocking/RhinoMockRepositoryProxy.cs =================================================================== --- trunk/Source/StructureMap.AutoMocking/RhinoMockRepositoryProxy.cs (rev 0) +++ trunk/Source/StructureMap.AutoMocking/RhinoMockRepositoryProxy.cs 2008-12-19 02:41:25 UTC (rev 199) @@ -0,0 +1,53 @@ +using System; +using System.Reflection; + +namespace StructureMap.AutoMocking +{ + public class RhinoMockRepositoryProxy + { + private readonly object _instance; + private readonly Func<Type, object[], object> _PartialMock; + private readonly Action<object> _Replay; + private readonly Func<Type, object[], object> _DynamicMock; + + public RhinoMockRepositoryProxy() + { + // We may consider allowing the consumer to pass in the MockRepository Type so we can avoid any possible Assembly conflict issues. + // (The assumption being that their test project already has a reference to Rhino.Mocks.) + // ex: var myclass = RhinoAutoMocker<MyClass>(MockMode.AAA, typeof(MockRepository) + var RhinoMocks = Assembly.Load("Rhino.Mocks"); + var mockRepositoryType = RhinoMocks.GetType("Rhino.Mocks.MockRepository"); + if (mockRepositoryType == null) throw new InvalidOperationException("Unable to find Type Rhino.Mocks.MockRepository in assembly " + RhinoMocks.Location); + + _instance = Activator.CreateInstance(mockRepositoryType); + var methodInfo = mockRepositoryType.GetMethod("DynamicMock", new[] { typeof(Type), typeof(object[]) }); + if (methodInfo == null) throw new InvalidOperationException("Unable to find method DynamicMock(Type, object[]) on MockRepository."); + _DynamicMock = (Func<Type, object[], object>)Delegate.CreateDelegate(typeof(Func<Type, object[], object>), _instance, methodInfo); + + methodInfo = mockRepositoryType.GetMethod("PartialMock", new[] { typeof(Type), typeof(object[]) }); + if (methodInfo == null) throw new InvalidOperationException("Unable to find method PartialMock(Type, object[] on MockRepository."); + _PartialMock = (Func<Type, object[], object>)Delegate.CreateDelegate(typeof(Func<Type, object[], object>), _instance, methodInfo); + + + methodInfo = mockRepositoryType.GetMethod("Replay", new[] { typeof(object) }); + if (methodInfo == null) throw new InvalidOperationException("Unable to find method Replay(object) on MockRepository."); + _Replay = (Action<object>)Delegate.CreateDelegate(typeof(Action<object>), _instance, methodInfo); + } + + public object DynamicMock(Type type) + { + return _DynamicMock(type, null); + } + + public object PartialMock(Type type, object[] args) + { + return _PartialMock(type, args); + } + + public void Replay(object mock) + { + _Replay(mock); + } + + } +} \ No newline at end of file Modified: trunk/Source/StructureMap.AutoMocking/ServiceLocator.cs =================================================================== --- trunk/Source/StructureMap.AutoMocking/ServiceLocator.cs 2008-12-17 16:41:58 UTC (rev 198) +++ trunk/Source/StructureMap.AutoMocking/ServiceLocator.cs 2008-12-19 02:41:25 UTC (rev 199) @@ -1,5 +1,4 @@ using System; -using Rhino.Mocks; namespace StructureMap.AutoMocking { @@ -12,20 +11,11 @@ public class RhinoMocksClassicServiceLocator : ServiceLocator { - private readonly MockRepository _mocks; + private readonly RhinoMockRepositoryProxy _mocks = new RhinoMockRepositoryProxy(); - public RhinoMocksClassicServiceLocator(MockRepository repository) - { - _mocks = repository; - } - - public RhinoMocksClassicServiceLocator() : this(new MockRepository()) - { - } - public T Service<T>() where T : class { - return _mocks.DynamicMock<T>(); + return (T)_mocks.DynamicMock(typeof(T)); } public object Service(Type serviceType) @@ -35,31 +25,33 @@ public T PartialMock<T>(params object[] args) where T : class { - return _mocks.PartialMock<T>(args); + return (T)_mocks.PartialMock(typeof(T), args); } } public class RhinoMocksAAAServiceLocator : ServiceLocator { + private readonly RhinoMockRepositoryProxy _mocks = new RhinoMockRepositoryProxy(); + public T Service<T>() where T : class { - return MockRepository.GenerateMock<T>(); + var instance = (T)_mocks.DynamicMock(typeof (T)); + _mocks.Replay(instance); + return instance; } public object Service(Type serviceType) { - var mock = new MockRepository().DynamicMock(serviceType); - mock.Replay(); - - return mock; + var instance = _mocks.DynamicMock(serviceType); + _mocks.Replay(instance); + return instance; } public T PartialMock<T>(params object[] args) where T : class { - T mock = new MockRepository().PartialMock<T>(args); - mock.Replay(); - - return mock; + var instance = (T)_mocks.PartialMock(typeof(T), args); + _mocks.Replay(instance); + return instance; } } } \ No newline at end of file Modified: trunk/Source/StructureMap.AutoMocking/StructureMap.AutoMocking.csproj =================================================================== --- trunk/Source/StructureMap.AutoMocking/StructureMap.AutoMocking.csproj 2008-12-17 16:41:58 UTC (rev 198) +++ trunk/Source/StructureMap.AutoMocking/StructureMap.AutoMocking.csproj 2008-12-19 02:41:25 UTC (rev 199) @@ -53,10 +53,6 @@ <DocumentationFile>bin\Release\StructureMap.AutoMocking.XML</DocumentationFile> </PropertyGroup> <ItemGroup> - <Reference Include="Rhino.Mocks, Version=3.5.0.1337, Culture=neutral, PublicKeyToken=0b3305902db7183f, processorArchitecture=MSIL"> - <SpecificVersion>False</SpecificVersion> - <HintPath>..\..\bin\Rhino.Mocks.dll</HintPath> - </Reference> <Reference Include="System" /> <Reference Include="System.Core"> <RequiredTargetFramework>3.5</RequiredTargetFramework> @@ -72,6 +68,7 @@ <Compile Include="AutoMocker.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="RhinoAutoMocker.cs" /> + <Compile Include="RhinoMockRepositoryProxy.cs" /> <Compile Include="ServiceLocator.cs" /> </ItemGroup> <ItemGroup> @@ -110,4 +107,4 @@ <Target Name="AfterBuild"> </Target> --> -</Project> \ No newline at end of file +</Project> Added: trunk/Source/StructureMap.Testing/AutoMocking/RhinoMockRepositoryProxyTester.cs =================================================================== --- trunk/Source/StructureMap.Testing/AutoMocking/RhinoMockRepositoryProxyTester.cs (rev 0) +++ trunk/Source/StructureMap.Testing/AutoMocking/RhinoMockRepositoryProxyTester.cs 2008-12-19 02:41:25 UTC (rev 199) @@ -0,0 +1,66 @@ +using NUnit.Framework; +using StructureMap.AutoMocking; +using Rhino.Mocks; + +namespace StructureMap.Testing.AutoMocking +{ + [TestFixture] + public class RhinoMockRepositoryProxyTester + { + [Test] + public void can_make_dynamic_mocks() + { + var mockRepository = new RhinoMockRepositoryProxy(); + var fooMock = mockRepository.DynamicMock(typeof(ITestMocks)); + + fooMock.ShouldNotBeNull(); + } + + [Test] + public void can_put_mock_in_replay_mode() + { + var mockRepository = new RhinoMockRepositoryProxy(); + var test = (ITestMocks)mockRepository.DynamicMock(typeof(ITestMocks)); + + mockRepository.Replay(test); + + test.Stub(t => t.Answer()).Return("YES"); + test.ShouldNotBeNull(); + test.Answer().ShouldEqual("YES"); + } + + [Test] + public void can_make_partial_mocks() + { + var mockRepository = new RhinoMockRepositoryProxy(); + var testPartials = (TestPartials)mockRepository.PartialMock(typeof(TestPartials), new object[0]); + + testPartials.ShouldNotBeNull(); + mockRepository.Replay(testPartials); + testPartials.Concrete().ShouldEqual("Concrete"); + testPartials.Virtual().ShouldEqual("Virtual"); + + testPartials.Stub(t => t.Virtual()).Return("MOCKED!"); + testPartials.Virtual().ShouldEqual("MOCKED!"); + } + + } + + public interface ITestMocks + { + string Answer(); + } + + public class TestPartials + { + public string Concrete() + { + return "Concrete"; + } + + public virtual string Virtual() + { + return "Virtual"; + } + } +} \ No newline at end of file Modified: trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj =================================================================== --- trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj 2008-12-17 16:41:58 UTC (rev 198) +++ trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj 2008-12-19 02:41:25 UTC (rev 199) @@ -170,6 +170,7 @@ <SubType>Code</SubType> </Compile> <Compile Include="AutoMocking\RhinoAutoMockerTester.cs" /> + <Compile Include="AutoMocking\RhinoMockRepositoryProxyTester.cs" /> <Compile Include="BuildSessionTester.cs" /> <Compile Include="Configuration\ConfigurationParserBuilderTester.cs" /> <Compile Include="Configuration\ConfigurationParserTester.cs" /> @@ -445,4 +446,4 @@ <PostBuildEvent> </PostBuildEvent> </PropertyGroup> -</Project> \ No newline at end of file +</Project> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fli...@us...> - 2008-12-17 16:42:12
|
Revision: 198 http://structuremap.svn.sourceforge.net/structuremap/?rev=198&view=rev Author: flimflan Date: 2008-12-17 16:41:58 +0000 (Wed, 17 Dec 2008) Log Message: ----------- - Fixed TryGetInstance methods so that they are static - Added early code for IContainer debugger visualizer (use at your own risk - see README.TXT) Modified Paths: -------------- trunk/README.TXT trunk/Source/StructureMap/ObjectFactory.cs trunk/Source/StructureMap.sln trunk/cruise.build Added Paths: ----------- trunk/Source/StructureMap.DebuggerVisualizers/ trunk/Source/StructureMap.DebuggerVisualizers/ContainerDetail.cs trunk/Source/StructureMap.DebuggerVisualizers/ContainerForm.Designer.cs trunk/Source/StructureMap.DebuggerVisualizers/ContainerForm.cs trunk/Source/StructureMap.DebuggerVisualizers/ContainerForm.resx trunk/Source/StructureMap.DebuggerVisualizers/ContainerVisualizer.cs trunk/Source/StructureMap.DebuggerVisualizers/ContainerVisualizerObjectSource.cs trunk/Source/StructureMap.DebuggerVisualizers/DisplayHelper.cs trunk/Source/StructureMap.DebuggerVisualizers/Properties/ trunk/Source/StructureMap.DebuggerVisualizers/Properties/AssemblyInfo.cs trunk/Source/StructureMap.DebuggerVisualizers/StructureMap.DebuggerVisualizers.csproj Removed Paths: ------------- trunk/Source/StructureMap.lnk Modified: trunk/README.TXT =================================================================== --- trunk/README.TXT 2008-12-17 04:35:54 UTC (rev 197) +++ trunk/README.TXT 2008-12-17 16:41:58 UTC (rev 198) @@ -1,10 +1,15 @@ To start using StructureMap, either use the DLL's in the "deploy" folder or click on the RunBuild.BAT file to run the full NAnt build. There is a known issue with the build "sticking" on the custom NAnt tasks. If this happens, delete the copies of StructureMap.Dll and StructureMap.DeploymentTasks.Dll in the bin\NAnt folder. Look in the "build" directory for the build products. +To enable the debugger visualizers in Visual Studio 2008, put a copy of StructureMap.dll and StructureMap.DebuggerVisualizers.dll in "<My Documents>\Visual Studio 2008\Visualizers" +**WARNING: The visualizer is very early and not well tested. You may experience issues (unhandled exceptions while using the visualizer) if the version of StructureMap.dll in your project is not the exact version in your Visualizers folder. + A copy of the StructureMap website and documentation is in the "Docs" folder. -Contact jer...@ya... with any questions or bugs. +Please post any questions or bugs to the StructureMap Users mailing list: +http://groups.google.com/group/structuremap-users + The latest code and documentation is available on SourceForge: http://structuremap.sourceforge.net/ Modified: trunk/Source/StructureMap/ObjectFactory.cs =================================================================== --- trunk/Source/StructureMap/ObjectFactory.cs 2008-12-17 04:35:54 UTC (rev 197) +++ trunk/Source/StructureMap/ObjectFactory.cs 2008-12-17 16:41:58 UTC (rev 198) @@ -13,7 +13,7 @@ /// The main static Facade for the StructureMap container /// </summary> [EnvironmentPermission(SecurityAction.Assert, Read = "COMPUTERNAME")] - public class ObjectFactory + public static class ObjectFactory { private static readonly object _lockObject = new object(); private static Container _container; @@ -379,7 +379,7 @@ /// <param name="instanceKey"></param> /// <param name="instance"></param> /// <returns></returns> - public object TryGetInstance(Type pluginType, string instanceKey) + public static object TryGetInstance(Type pluginType, string instanceKey) { return container.TryGetInstance(pluginType, instanceKey); } @@ -390,7 +390,7 @@ /// <param name="pluginType"></param> /// <param name="instance"></param> /// <returns></returns> - public object TryGetInstance(Type pluginType) + public static object TryGetInstance(Type pluginType) { return container.TryGetInstance(pluginType); } @@ -401,7 +401,7 @@ /// <typeparam name="T"></typeparam> /// <param name="instance"></param> /// <returns></returns> - public T TryGetInstance<T>() + public static T TryGetInstance<T>() { return container.TryGetInstance<T>(); } @@ -412,7 +412,7 @@ /// <typeparam name="T"></typeparam> /// <param name="instance"></param> /// <returns></returns> - public T TryGetInstance<T>(string instanceKey) + public static T TryGetInstance<T>(string instanceKey) { return container.TryGetInstance<T>(instanceKey); } Property changes on: trunk/Source/StructureMap.DebuggerVisualizers ___________________________________________________________________ Added: svn:ignore + [Bb]in obj [Dd]ebug [Rr]elease *.user *.aps *.eto Added: trunk/Source/StructureMap.DebuggerVisualizers/ContainerDetail.cs =================================================================== --- trunk/Source/StructureMap.DebuggerVisualizers/ContainerDetail.cs (rev 0) +++ trunk/Source/StructureMap.DebuggerVisualizers/ContainerDetail.cs 2008-12-17 16:41:58 UTC (rev 198) @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; + +namespace StructureMap.DebuggerVisualizers +{ + [Serializable] + public class ContainerDetail + { + private readonly string[] _sources; + private readonly PluginTypeDetail[] _pluginTypeDetails; + + public ContainerDetail(string[] sources, PluginTypeDetail[] types) + { + _sources = sources; + _pluginTypeDetails = types; + } + + public string[] Sources + { + get { return _sources; } + } + + public PluginTypeDetail[] PluginTypes + { + get { return _pluginTypeDetails; } + } + } + + [Serializable] + public class PluginTypeDetail + { + private readonly Type _type; + private readonly Type _buildPolicyType; + private readonly InstanceDetail[] instanceDetails; + private readonly IList<InstanceDetail> _instances = new List<InstanceDetail>(); + + public PluginTypeDetail(Type type, Type buildPolicyType, InstanceDetail[] instanceDetails) + { + _type = type; + _buildPolicyType = buildPolicyType; + this.instanceDetails = instanceDetails; + } + + public InstanceDetail[] Instances + { + get { return instanceDetails; } + } + + public Type BuildPolicy + { + get { return _buildPolicyType; } + } + + public Type Type + { + get { return _type; } + } + } + + [Serializable] + public class InstanceDetail + { + private readonly string _name; + private readonly string _description; + private readonly Type _concreteType; + + public InstanceDetail(string name, string description, Type concreteType) + { + _name = name; + _description = description; + _concreteType = concreteType; + } + + public Type ConcreteType + { + get { return _concreteType; } + } + + public string Description + { + get { return _description; } + } + + public string Name + { + get { return _name; } + } + } + +} \ No newline at end of file Property changes on: trunk/Source/StructureMap.DebuggerVisualizers/ContainerDetail.cs ___________________________________________________________________ Added: svn:mergeinfo + Added: trunk/Source/StructureMap.DebuggerVisualizers/ContainerForm.Designer.cs =================================================================== --- trunk/Source/StructureMap.DebuggerVisualizers/ContainerForm.Designer.cs (rev 0) +++ trunk/Source/StructureMap.DebuggerVisualizers/ContainerForm.Designer.cs 2008-12-17 16:41:58 UTC (rev 198) @@ -0,0 +1,68 @@ +namespace StructureMap.DebuggerVisualizers +{ + partial class ContainerForm + { + /// <summary> + /// Required designer variable. + /// </summary> + private System.ComponentModel.IContainer components = null; + + /// <summary> + /// Clean up any resources being used. + /// </summary> + /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// <summary> + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// </summary> + private void InitializeComponent() + { + this.BrowserTree = new System.Windows.Forms.TreeView(); + this.SuspendLayout(); + // + // BrowserTree + // + this.BrowserTree.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.BrowserTree.Location = new System.Drawing.Point(12, 12); + this.BrowserTree.Name = "BrowserTree"; + this.BrowserTree.ShowRootLines = false; + this.BrowserTree.Size = new System.Drawing.Size(548, 249); + this.BrowserTree.TabIndex = 4; + this.BrowserTree.AfterExpand += new System.Windows.Forms.TreeViewEventHandler(this.BrowserTree_AfterExpand); + // + // ContainerForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(572, 273); + this.Controls.Add(this.BrowserTree); + this.MinimizeBox = false; + this.MinimumSize = new System.Drawing.Size(280, 80); + this.Name = "ContainerForm"; + this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Show; + this.Text = "StructureMap Container Browser"; + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TreeView BrowserTree; + + + + } +} \ No newline at end of file Added: trunk/Source/StructureMap.DebuggerVisualizers/ContainerForm.cs =================================================================== --- trunk/Source/StructureMap.DebuggerVisualizers/ContainerForm.cs (rev 0) +++ trunk/Source/StructureMap.DebuggerVisualizers/ContainerForm.cs 2008-12-17 16:41:58 UTC (rev 198) @@ -0,0 +1,88 @@ +using System.Windows.Forms; +using System.Linq; + +namespace StructureMap.DebuggerVisualizers +{ + public partial class ContainerForm : Form + { + + public ContainerForm() + { + InitializeComponent(); + } + + public ContainerForm(ContainerDetail containerDetail) + { + InitializeComponent(); + buildTree(BrowserTree, containerDetail); + } + + private static void buildTree(TreeView tree, ContainerDetail container) + { + var sourcesRoot = buildConfigurationSources(tree, container); + var pluginTypesRoot = buildPluginTypes(tree, container); + + pluginTypesRoot.Expand(); + sourcesRoot.Expand(); + } + + private static TreeNode buildPluginTypes(TreeView tree, ContainerDetail container) + { + var pluginTypesRoot = tree.Nodes.Add("PluginTypes"); + foreach (var pluginType in container.PluginTypes.OrderBy(t => t.Type.Name)) + { + addPluginType(pluginTypesRoot, pluginType); + } + return pluginTypesRoot; + } + + private static TreeNode buildConfigurationSources(TreeView tree, ContainerDetail container) + { + var sourcesRoot = tree.Nodes.Add("Configuration Sources"); + foreach (var source in container.Sources.OrderBy(s => s)) + { + addSource(sourcesRoot, source); + } + return sourcesRoot; + } + + private static void addSource(TreeNode root, string source) + { + root.Nodes.Add(source); + } + + private static void addPluginType(TreeNode pluginTypesRoot, PluginTypeDetail pluginType) + { + var pluginNode = pluginTypesRoot.Nodes.Add(pluginType.Type.AsCSharp()); + pluginNode.Nodes.Add("FullName: " + pluginType.Type.AsCSharp(t=>t.FullName ?? t.Name)); + pluginNode.Nodes.Add("Assembly: " + pluginType.Type.Assembly); + pluginNode.Nodes.Add("BuildPolicy: " + pluginType.BuildPolicy.Name); + if (pluginType.Instances.Length == 0) return; + + var instancesRoot = pluginNode.Nodes.Add("Instances"); + foreach (var instance in pluginType.Instances.OrderBy(i => i.Name)) + { + addInstance(instancesRoot, instance); + } + } + + private static void addInstance(TreeNode instancesRoot, InstanceDetail instance) + { + var instanceNode = instancesRoot.Nodes.Add("Name: " + instance.Name); + if (instance.Name != instance.Description) + { + instanceNode.Nodes.Add("Description: " + instance.Description); + } + if (instance.ConcreteType != null) + { + instanceNode.Nodes.Add("ConcreteType: " + instance.ConcreteType.AsCSharp()); + } + } + + private void BrowserTree_AfterExpand(object sender, TreeViewEventArgs e) + { + if (e.Node.Level < 1) return; + e.Node.ExpandAll(); + } + } +} Added: trunk/Source/StructureMap.DebuggerVisualizers/ContainerForm.resx =================================================================== --- trunk/Source/StructureMap.DebuggerVisualizers/ContainerForm.resx (rev 0) +++ trunk/Source/StructureMap.DebuggerVisualizers/ContainerForm.resx 2008-12-17 16:41:58 UTC (rev 198) @@ -0,0 +1,120 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" use="required" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> +</root> \ No newline at end of file Added: trunk/Source/StructureMap.DebuggerVisualizers/ContainerVisualizer.cs =================================================================== --- trunk/Source/StructureMap.DebuggerVisualizers/ContainerVisualizer.cs (rev 0) +++ trunk/Source/StructureMap.DebuggerVisualizers/ContainerVisualizer.cs 2008-12-17 16:41:58 UTC (rev 198) @@ -0,0 +1,26 @@ +using System; +using System.Diagnostics; +using Microsoft.VisualStudio.DebuggerVisualizers; +using StructureMap; +using StructureMap.DebuggerVisualizers; + +[assembly: DebuggerVisualizer(typeof(ContainerVisualizer), typeof(ContainerVisualizerObjectSource), Target = typeof(Container), Description = "Container Browser")] + +namespace StructureMap.DebuggerVisualizers +{ + + public class ContainerVisualizer : DialogDebuggerVisualizer + { + private IDialogVisualizerService modalService; + + protected override void Show(IDialogVisualizerService windowService, IVisualizerObjectProvider objectProvider) + { + modalService = windowService; + if (modalService == null) throw new NotSupportedException("This debugger does not support modal visualizers"); + + var containerDetail = (ContainerDetail)objectProvider.GetObject(); + var form = new ContainerForm(containerDetail); + modalService.ShowDialog(form); + } + } +} Added: trunk/Source/StructureMap.DebuggerVisualizers/ContainerVisualizerObjectSource.cs =================================================================== --- trunk/Source/StructureMap.DebuggerVisualizers/ContainerVisualizerObjectSource.cs (rev 0) +++ trunk/Source/StructureMap.DebuggerVisualizers/ContainerVisualizerObjectSource.cs 2008-12-17 16:41:58 UTC (rev 198) @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.IO; +using Microsoft.VisualStudio.DebuggerVisualizers; +using System.Linq; +using StructureMap.Pipeline; + +namespace StructureMap.DebuggerVisualizers +{ + public class ContainerVisualizerObjectSource : VisualizerObjectSource + { + public override void GetData(object target, Stream outgoingData) + { + var container = target as Container; + if (container == null) throw new InvalidOperationException("This visualizer does not support Type: " + target.GetType().Name); + + var details = BuildContainerDetails(container); + Serialize(outgoingData, details); + } + + public static ContainerDetail BuildContainerDetails(Container container) + { + IList<PluginTypeDetail> pluginTypeDetails = new List<PluginTypeDetail>(); + foreach (var pluginType in container.Model.PluginTypes) + { + IList<InstanceDetail> instances = new List<InstanceDetail>(); + IList<IInstance> usedInstances = new List<IInstance>(); + + if (pluginType.Default != null) + { + instances.Add(buildInstanceDetail(pluginType.Default)); + usedInstances.Add(pluginType.Default); + } + foreach (var instance in pluginType.Instances) + { + if (usedInstances.Contains(instance)) continue; + instances.Add(buildInstanceDetail(instance)); + } + + var pluginTypeDetail = new PluginTypeDetail(pluginType.PluginType, pluginType.Policy.GetType(), instances.ToArray()); + pluginTypeDetails.Add(pluginTypeDetail); + } + + return new ContainerDetail(container.PluginGraph.Log.Sources, pluginTypeDetails.ToArray()); + } + + private static InstanceDetail buildInstanceDetail(IInstance instance) + { + return new InstanceDetail(instance.Name, instance.Description, instance.ConcreteType); + } + } +} \ No newline at end of file Added: trunk/Source/StructureMap.DebuggerVisualizers/DisplayHelper.cs =================================================================== --- trunk/Source/StructureMap.DebuggerVisualizers/DisplayHelper.cs (rev 0) +++ trunk/Source/StructureMap.DebuggerVisualizers/DisplayHelper.cs 2008-12-17 16:41:58 UTC (rev 198) @@ -0,0 +1,30 @@ +using System; +using System.Linq; + +namespace StructureMap.DebuggerVisualizers +{ + public static class DisplayHelper + { + public static string AsCSharp(this Type type) + { + return type.AsCSharp(t => t.Name); + } + public static string AsCSharp(this Type type, Func<Type, string> selector) + { + var typeName = selector(type) ?? string.Empty; + if (type.IsGenericType) + { + var genericParamSelector = type.IsGenericTypeDefinition ? t => t.Name : selector; + var genericTypeList = String.Join(",", type.GetGenericArguments().Select(genericParamSelector).ToArray()); + var tickLocation = typeName.IndexOf('`'); + if (tickLocation >= 0) + { + typeName = typeName.Substring(0, tickLocation); + } + return string.Format("{0}<{1}>", typeName, genericTypeList); + } + return typeName; + } + + } +} Added: trunk/Source/StructureMap.DebuggerVisualizers/Properties/AssemblyInfo.cs =================================================================== --- trunk/Source/StructureMap.DebuggerVisualizers/Properties/AssemblyInfo.cs (rev 0) +++ trunk/Source/StructureMap.DebuggerVisualizers/Properties/AssemblyInfo.cs 2008-12-17 16:41:58 UTC (rev 198) @@ -0,0 +1,4 @@ +using System.Reflection; + +[assembly: AssemblyTitle("StructureMap.DebuggerVisualizers")] +[assembly: AssemblyDescription("Enhances the Visual Studio debugger to provide better support for StructureMap types.")] Added: trunk/Source/StructureMap.DebuggerVisualizers/StructureMap.DebuggerVisualizers.csproj =================================================================== --- trunk/Source/StructureMap.DebuggerVisualizers/StructureMap.DebuggerVisualizers.csproj (rev 0) +++ trunk/Source/StructureMap.DebuggerVisualizers/StructureMap.DebuggerVisualizers.csproj 2008-12-17 16:41:58 UTC (rev 198) @@ -0,0 +1,87 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProductVersion>9.0.21022</ProductVersion> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{F023DA4D-0B7D-4836-A56A-21F22A0A2D71}</ProjectGuid> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>StructureMap.DebuggerVisualizers</RootNamespace> + <AssemblyName>StructureMap.DebuggerVisualizers</AssemblyName> + <TargetFrameworkVersion>v3.5</TargetFrameworkVersion> + <FileAlignment>512</FileAlignment> + <SignAssembly>true</SignAssembly> + <AssemblyOriginatorKeyFile>..\structuremap.snk</AssemblyOriginatorKeyFile> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <ItemGroup> + <Reference Include="Microsoft.VisualStudio.DebuggerVisualizers, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" /> + <Reference Include="System" /> + <Reference Include="System.Core"> + <RequiredTargetFramework>3.5</RequiredTargetFramework> + </Reference> + <Reference Include="System.Drawing" /> + <Reference Include="System.Windows.Forms" /> + <Reference Include="System.Data" /> + <Reference Include="System.Xml" /> + </ItemGroup> + <ItemGroup> + <Compile Include="..\CommonAssemblyInfo.cs"> + <Link>CommonAssemblyInfo.cs</Link> + </Compile> + <Compile Include="ContainerForm.cs"> + <SubType>Form</SubType> + </Compile> + <Compile Include="ContainerForm.Designer.cs"> + <DependentUpon>ContainerForm.cs</DependentUpon> + </Compile> + <Compile Include="ContainerVisualizer.cs" /> + <Compile Include="ContainerVisualizerObjectSource.cs" /> + <Compile Include="ContainerDetail.cs" /> + <Compile Include="DisplayHelper.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\StructureMap\StructureMap.csproj"> + <Project>{3F36EA80-2F9A-4DAD-BA27-5AC6163A2EE3}</Project> + <Name>StructureMap</Name> + </ProjectReference> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="ContainerForm.resx"> + <DependentUpon>ContainerForm.cs</DependentUpon> + <SubType>Designer</SubType> + </EmbeddedResource> + </ItemGroup> + <ItemGroup> + <None Include="..\structuremap.snk"> + <Link>Properties\structuremap.snk</Link> + </None> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> +</Project> \ No newline at end of file Deleted: trunk/Source/StructureMap.lnk =================================================================== (Binary files differ) Modified: trunk/Source/StructureMap.sln =================================================================== --- trunk/Source/StructureMap.sln 2008-12-17 04:35:54 UTC (rev 197) +++ trunk/Source/StructureMap.sln 2008-12-17 16:41:58 UTC (rev 198) @@ -53,6 +53,10 @@ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HTML", "HTML\HTML.csproj", "{A6358895-641F-4CC2-BE8E-C61EBE1DBEB9}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StructureMap.DebuggerVisualizers", "StructureMap.DebuggerVisualizers\StructureMap.DebuggerVisualizers.csproj", "{F023DA4D-0B7D-4836-A56A-21F22A0A2D71}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StructureMap.DebuggerVisualizers.Testing", "StructureMap.DebuggerVisualizers.Testing\StructureMap.DebuggerVisualizers.Testing.csproj", "{13C368E6-A7BE-46E8-8CFB-64010C825748}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Build|.NET = Build|.NET @@ -243,6 +247,36 @@ {A6358895-641F-4CC2-BE8E-C61EBE1DBEB9}.Release|Any CPU.ActiveCfg = Release|Any CPU {A6358895-641F-4CC2-BE8E-C61EBE1DBEB9}.Release|Any CPU.Build.0 = Release|Any CPU {A6358895-641F-4CC2-BE8E-C61EBE1DBEB9}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {F023DA4D-0B7D-4836-A56A-21F22A0A2D71}.Build|.NET.ActiveCfg = Release|Any CPU + {F023DA4D-0B7D-4836-A56A-21F22A0A2D71}.Build|Any CPU.ActiveCfg = Release|Any CPU + {F023DA4D-0B7D-4836-A56A-21F22A0A2D71}.Build|Any CPU.Build.0 = Release|Any CPU + {F023DA4D-0B7D-4836-A56A-21F22A0A2D71}.Build|Mixed Platforms.ActiveCfg = Release|Any CPU + {F023DA4D-0B7D-4836-A56A-21F22A0A2D71}.Build|Mixed Platforms.Build.0 = Release|Any CPU + {F023DA4D-0B7D-4836-A56A-21F22A0A2D71}.Debug|.NET.ActiveCfg = Debug|Any CPU + {F023DA4D-0B7D-4836-A56A-21F22A0A2D71}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F023DA4D-0B7D-4836-A56A-21F22A0A2D71}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F023DA4D-0B7D-4836-A56A-21F22A0A2D71}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {F023DA4D-0B7D-4836-A56A-21F22A0A2D71}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {F023DA4D-0B7D-4836-A56A-21F22A0A2D71}.Release|.NET.ActiveCfg = Release|Any CPU + {F023DA4D-0B7D-4836-A56A-21F22A0A2D71}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F023DA4D-0B7D-4836-A56A-21F22A0A2D71}.Release|Any CPU.Build.0 = Release|Any CPU + {F023DA4D-0B7D-4836-A56A-21F22A0A2D71}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {F023DA4D-0B7D-4836-A56A-21F22A0A2D71}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {13C368E6-A7BE-46E8-8CFB-64010C825748}.Build|.NET.ActiveCfg = Release|Any CPU + {13C368E6-A7BE-46E8-8CFB-64010C825748}.Build|Any CPU.ActiveCfg = Release|Any CPU + {13C368E6-A7BE-46E8-8CFB-64010C825748}.Build|Any CPU.Build.0 = Release|Any CPU + {13C368E6-A7BE-46E8-8CFB-64010C825748}.Build|Mixed Platforms.ActiveCfg = Release|Any CPU + {13C368E6-A7BE-46E8-8CFB-64010C825748}.Build|Mixed Platforms.Build.0 = Release|Any CPU + {13C368E6-A7BE-46E8-8CFB-64010C825748}.Debug|.NET.ActiveCfg = Debug|Any CPU + {13C368E6-A7BE-46E8-8CFB-64010C825748}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {13C368E6-A7BE-46E8-8CFB-64010C825748}.Debug|Any CPU.Build.0 = Debug|Any CPU + {13C368E6-A7BE-46E8-8CFB-64010C825748}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {13C368E6-A7BE-46E8-8CFB-64010C825748}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {13C368E6-A7BE-46E8-8CFB-64010C825748}.Release|.NET.ActiveCfg = Release|Any CPU + {13C368E6-A7BE-46E8-8CFB-64010C825748}.Release|Any CPU.ActiveCfg = Release|Any CPU + {13C368E6-A7BE-46E8-8CFB-64010C825748}.Release|Any CPU.Build.0 = Release|Any CPU + {13C368E6-A7BE-46E8-8CFB-64010C825748}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {13C368E6-A7BE-46E8-8CFB-64010C825748}.Release|Mixed Platforms.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE Modified: trunk/cruise.build =================================================================== --- trunk/cruise.build 2008-12-17 04:35:54 UTC (rev 197) +++ trunk/cruise.build 2008-12-17 16:41:58 UTC (rev 198) @@ -48,11 +48,12 @@ <attributes> <attribute type="ComVisibleAttribute" value="false" /> <attribute type="AssemblyVersionAttribute" value="${assembly-version}" /> - <attribute type="AssemblyCopyrightAttribute" value="Copyright (c) 2007, Jeremy D. Miller" /> + <attribute type="AssemblyCopyrightAttribute" value="Copyright (c) 2003-2008, Jeremy D. Miller" /> <attribute type="AssemblyProductAttribute" value="StructureMap" /> <attribute type="AssemblyCompanyAttribute" value="" /> <attribute type="AssemblyConfigurationAttribute" value="${project.config}" /> <attribute type="AssemblyInformationalVersionAttribute" value="${assembly-version}" /> + <attribute type="AssemblyFileVersionAttribute" value="${assembly-version}" /> </attributes> <references> <include name="System.dll" /> @@ -100,9 +101,12 @@ <exec program="${nunit-console.exe}" workingdir="${build.dir}"> <arg value="StructureMap.Testing.dll" /> </exec> + <exec program="${nunit-console.exe}" workingdir="${build.dir}"> + <arg value="StructureMap.DebuggerVisualizers.Testing.exe" /> + </exec> - - </target> + + </target> <target name="runDoctor"> <echo message="Running StructureMapDoctor" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fli...@us...> - 2008-12-17 04:36:00
|
Revision: 197 http://structuremap.svn.sourceforge.net/structuremap/?rev=197&view=rev Author: flimflan Date: 2008-12-17 04:35:54 +0000 (Wed, 17 Dec 2008) Log Message: ----------- TryGetInstance is now available on ObjectFactory Modified Paths: -------------- trunk/Source/StructureMap/ObjectFactory.cs Modified: trunk/Source/StructureMap/ObjectFactory.cs =================================================================== --- trunk/Source/StructureMap/ObjectFactory.cs 2008-12-17 04:00:59 UTC (rev 196) +++ trunk/Source/StructureMap/ObjectFactory.cs 2008-12-17 04:35:54 UTC (rev 197) @@ -371,5 +371,51 @@ { return container.GetInstance<T>(args); } + + /// <summary> + /// Creates or finds the named instance of the pluginType. Returns null if the named instance is not known to the container. + /// </summary> + /// <param name="pluginType"></param> + /// <param name="instanceKey"></param> + /// <param name="instance"></param> + /// <returns></returns> + public object TryGetInstance(Type pluginType, string instanceKey) + { + return container.TryGetInstance(pluginType, instanceKey); + } + + /// <summary> + /// Creates or finds the default instance of the pluginType. Returns null if the pluginType is not known to the container. + /// </summary> + /// <param name="pluginType"></param> + /// <param name="instance"></param> + /// <returns></returns> + public object TryGetInstance(Type pluginType) + { + return container.TryGetInstance(pluginType); + } + + /// <summary> + /// Creates or finds the default instance of type T. Returns the default value of T if it is not known to the container. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="instance"></param> + /// <returns></returns> + public T TryGetInstance<T>() + { + return container.TryGetInstance<T>(); + } + + /// <summary> + /// Creates or finds the named instance of type T. Returns the default value of T if the named instance is not known to the container. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="instance"></param> + /// <returns></returns> + public T TryGetInstance<T>(string instanceKey) + { + return container.TryGetInstance<T>(instanceKey); + } + } } \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fli...@us...> - 2008-12-17 04:01:03
|
Revision: 196 http://structuremap.svn.sourceforge.net/structuremap/?rev=196&view=rev Author: flimflan Date: 2008-12-17 04:00:59 +0000 (Wed, 17 Dec 2008) Log Message: ----------- Attempt to resolve StructureMapException 400 when attempting to retrieve the same instance via ObjectFactory.GetInstance on multiple threads. Likely to occur in ASP.NET scenarios (retrieving controllers) Modified Paths: -------------- trunk/Source/StructureMap/Util/Cache.cs Modified: trunk/Source/StructureMap/Util/Cache.cs =================================================================== --- trunk/Source/StructureMap/Util/Cache.cs 2008-11-19 19:10:25 UTC (rev 195) +++ trunk/Source/StructureMap/Util/Cache.cs 2008-12-17 04:00:59 UTC (rev 196) @@ -15,6 +15,7 @@ private readonly Dictionary<KEY, VALUE> _values = new Dictionary<KEY, VALUE>(); private Func<VALUE, KEY> _getKey = delegate { throw new NotImplementedException(); }; + private readonly object _valuesLock = new object(); public Cache() { @@ -70,14 +71,7 @@ public void Store(KEY key, VALUE value) { - if (_values.ContainsKey(key)) - { - _values[key] = value; - } - else - { - _values.Add(key, value); - } + _values[key] = value; } public void Fill(KEY key, VALUE value) @@ -94,8 +88,15 @@ { if (!_values.ContainsKey(key)) { - VALUE value = _onMissing(key); - _values.Add(key, value); + lock (_valuesLock) + { + if (!_values.ContainsKey(key)) + { + // Potential deadlock if _onMissing attempts to retrieve the same key + VALUE value = _onMissing(key); + _values.Add(key, value); + } + } } return _values[key]; @@ -154,10 +155,7 @@ public void Remove(KEY key) { - if (_values.ContainsKey(key)) - { - _values.Remove(key); - } + _values.Remove(key); } } } \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jer...@us...> - 2008-11-19 19:10:28
|
Revision: 195 http://structuremap.svn.sourceforge.net/structuremap/?rev=195&view=rev Author: jeremydmiller Date: 2008-11-19 19:10:25 +0000 (Wed, 19 Nov 2008) Log Message: ----------- Mild fix for a production issue with auto scanning open generic types Modified Paths: -------------- trunk/Source/StructureMap/Graph/FindAllTypesFilter.cs trunk/Source/StructureMap/Graph/TypeRules.cs trunk/Source/StructureMap/Pipeline/HttpContextBuildPolicy.cs trunk/Source/StructureMap/Pipeline/HybridBuildPolicy.cs trunk/Source/StructureMap.Testing/ModelQueryTester.cs Modified: trunk/Source/StructureMap/Graph/FindAllTypesFilter.cs =================================================================== --- trunk/Source/StructureMap/Graph/FindAllTypesFilter.cs 2008-10-27 02:13:42 UTC (rev 194) +++ trunk/Source/StructureMap/Graph/FindAllTypesFilter.cs 2008-11-19 19:10:25 UTC (rev 195) @@ -15,6 +15,8 @@ public void Process(Type type, PluginGraph graph) { + + if (CanBeCast(_pluginType, type)) { graph.AddType(_pluginType, type); Modified: trunk/Source/StructureMap/Graph/TypeRules.cs =================================================================== --- trunk/Source/StructureMap/Graph/TypeRules.cs 2008-10-27 02:13:42 UTC (rev 194) +++ trunk/Source/StructureMap/Graph/TypeRules.cs 2008-11-19 19:10:25 UTC (rev 195) @@ -22,14 +22,25 @@ return false; } - if (GenericsPluginGraph.CanBeCast(pluginType, pluggedType)) + if (IsGeneric(pluginType)) { - return true; + return GenericsPluginGraph.CanBeCast(pluginType, pluggedType); } + if (IsGeneric(pluggedType)) + { + return false; + } + + return pluginType.IsAssignableFrom(pluggedType); } + public static bool IsGeneric(Type pluggedType) + { + return pluggedType.IsGenericTypeDefinition || pluggedType.ContainsGenericParameters; + } + /// <summary> /// Determines if the PluggedType is a valid Plugin into the /// PluginType Modified: trunk/Source/StructureMap/Pipeline/HttpContextBuildPolicy.cs =================================================================== --- trunk/Source/StructureMap/Pipeline/HttpContextBuildPolicy.cs 2008-10-27 02:13:42 UTC (rev 194) +++ trunk/Source/StructureMap/Pipeline/HttpContextBuildPolicy.cs 2008-11-19 19:10:25 UTC (rev 195) @@ -5,8 +5,9 @@ { public class HttpContextBuildPolicy : CacheInterceptor { - private readonly string _prefix = Guid.NewGuid().ToString(); + private string _prefix = Guid.NewGuid().ToString(); + public static bool HasContext() { return HttpContext.Current != null; Modified: trunk/Source/StructureMap/Pipeline/HybridBuildPolicy.cs =================================================================== --- trunk/Source/StructureMap/Pipeline/HybridBuildPolicy.cs 2008-10-27 02:13:42 UTC (rev 194) +++ trunk/Source/StructureMap/Pipeline/HybridBuildPolicy.cs 2008-11-19 19:10:25 UTC (rev 195) @@ -4,15 +4,25 @@ { public class HybridBuildPolicy : IBuildInterceptor { + private readonly IBuildInterceptor _http; + private readonly IBuildInterceptor _threadLocal; + + public HybridBuildPolicy() + { + _http = new HttpContextBuildPolicy(); + _threadLocal = new ThreadLocalStoragePolicy(); + } + private IBuildPolicy _innerPolicy; + private IBuildInterceptor interceptor { get { return HttpContextBuildPolicy.HasContext() - ? (IBuildInterceptor)new HttpContextBuildPolicy(){InnerPolicy = _innerPolicy} - : new ThreadLocalStoragePolicy(){InnerPolicy = _innerPolicy}; + ? _http + : _threadLocal; } } @@ -21,7 +31,12 @@ public IBuildPolicy InnerPolicy { get { return _innerPolicy; } - set { _innerPolicy = value; } + set + { + _http.InnerPolicy = value; + _threadLocal.InnerPolicy = value; + _innerPolicy = value; + } } public object Build(BuildSession buildSession, Type pluginType, Instance instance) Modified: trunk/Source/StructureMap.Testing/ModelQueryTester.cs =================================================================== --- trunk/Source/StructureMap.Testing/ModelQueryTester.cs 2008-10-27 02:13:42 UTC (rev 194) +++ trunk/Source/StructureMap.Testing/ModelQueryTester.cs 2008-11-19 19:10:25 UTC (rev 195) @@ -1,5 +1,6 @@ using System; using System.Data; +using System.Data.SqlClient; using System.Linq; using NUnit.Framework; using StructureMap.Configuration.DSL; @@ -31,6 +32,7 @@ } + [SetUp] public void SetUp() { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jer...@us...> - 2008-10-27 02:13:46
|
Revision: 194 http://structuremap.svn.sourceforge.net/structuremap/?rev=194&view=rev Author: jeremydmiller Date: 2008-10-27 02:13:42 +0000 (Mon, 27 Oct 2008) Log Message: ----------- some cleanup on the NAnt file, and the CHM file Modified Paths: -------------- trunk/README.TXT trunk/Source/StructureMap.AutoMocking/StructureMap.AutoMocking.csproj trunk/cruise.build Added Paths: ----------- trunk/StructureMap.chm Modified: trunk/README.TXT =================================================================== --- trunk/README.TXT 2008-10-27 01:07:28 UTC (rev 193) +++ trunk/README.TXT 2008-10-27 02:13:42 UTC (rev 194) @@ -1,4 +1,4 @@ -To start using StructureMap, either use the DLL's in the build folder or click on the RunBuild.BAT file to run the full NAnt build. There is a known issue with the build "sticking" on the custom NAnt tasks. If this happens, delete the copies of StructureMap.Dll and StructureMap.DeploymentTasks.Dll in the bin\NAnt folder. Look in the "build" directory for the build products. +To start using StructureMap, either use the DLL's in the "deploy" folder or click on the RunBuild.BAT file to run the full NAnt build. There is a known issue with the build "sticking" on the custom NAnt tasks. If this happens, delete the copies of StructureMap.Dll and StructureMap.DeploymentTasks.Dll in the bin\NAnt folder. Look in the "build" directory for the build products. A copy of the StructureMap website and documentation is in the "Docs" folder. Modified: trunk/Source/StructureMap.AutoMocking/StructureMap.AutoMocking.csproj =================================================================== --- trunk/Source/StructureMap.AutoMocking/StructureMap.AutoMocking.csproj 2008-10-27 01:07:28 UTC (rev 193) +++ trunk/Source/StructureMap.AutoMocking/StructureMap.AutoMocking.csproj 2008-10-27 02:13:42 UTC (rev 194) @@ -41,6 +41,7 @@ <DefineConstants>DEBUG;TRACE</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> + <DocumentationFile>bin\Debug\StructureMap.AutoMocking.XML</DocumentationFile> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <DebugType>pdbonly</DebugType> @@ -49,6 +50,7 @@ <DefineConstants>TRACE</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> + <DocumentationFile>bin\Release\StructureMap.AutoMocking.XML</DocumentationFile> </PropertyGroup> <ItemGroup> <Reference Include="Rhino.Mocks, Version=3.5.0.1337, Culture=neutral, PublicKeyToken=0b3305902db7183f, processorArchitecture=MSIL"> Added: trunk/StructureMap.chm =================================================================== (Binary files differ) Property changes on: trunk/StructureMap.chm ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Modified: trunk/cruise.build =================================================================== --- trunk/cruise.build 2008-10-27 01:07:28 UTC (rev 193) +++ trunk/cruise.build 2008-10-27 02:13:42 UTC (rev 194) @@ -121,17 +121,27 @@ <target name="post-clean"> - <call target="cleanJunk" /> + + <delete dir="deploy" failonerror="false" /> + <mkdir dir="deploy" /> - <delete> - <fileset basedir="${build.dir}"> - <include name="*.xml" /> - <include name="*.config" /> - <exclude name="structuremap.xml" /> - </fileset> - </delete> + <copy todir="deploy" flatten="true" overwrite="true"> + <fileset basedir="source\StructureMap.Testing\bin\${project.config}"> + <include name="StructureMap.dll" /> + <include name="StructureMap.xml" /> + <include name="StructureMap.AutoMocking.dll" /> + <include name="StructureMap.AutoMocking.xml" /> + </fileset> + </copy> + <copy todir="deploy" file="bin\Rhino.Mocks.dll"/> + <copy todir="deploy" file="StructureMap.chm"/> + + <copy todir="deploy" file="Source\StructureMapDoctor\bin\${project.config}\StructureMapDoctor.exe" /> + + <call target="cleanJunk" /> </target> + <target name="archive"> <if test="${property::exists('CCNetLabel')}"> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jer...@us...> - 2008-10-27 01:07:32
|
Revision: 193 http://structuremap.svn.sourceforge.net/structuremap/?rev=193&view=rev Author: jeremydmiller Date: 2008-10-27 01:07:28 +0000 (Mon, 27 Oct 2008) Log Message: ----------- Making the final check in (knock on wood) for the 2.5 binary release Modified Paths: -------------- trunk/Source/HTML/ConfiguringStructureMap.htm trunk/Source/StructureMap/Configuration/DSL/Expressions/CreatePluginFamilyExpression.cs trunk/Source/StructureMap/Configuration/DSL/Expressions/GenericFamilyExpression.cs trunk/Source/StructureMap/Configuration/DSL/Expressions/InstanceExpression.cs trunk/Source/StructureMap/Configuration/DSL/Expressions/ProfileExpression.cs trunk/Source/StructureMap/Configuration/DSL/Registry.cs trunk/Source/StructureMap/ConfigurationExpression.cs trunk/Source/StructureMap/Graph/AssemblyScanner.cs trunk/Source/StructureMap/InitializationExpression.cs trunk/Source/StructureMap/Interceptors/FilteredInstanceInterceptor.cs trunk/Source/StructureMap/Interceptors/InstanceInterceptor.cs trunk/Source/StructureMap/Pipeline/BuildFrame.cs trunk/Source/StructureMap/Pipeline/ConfiguredInstance.Expressions.cs trunk/Source/StructureMap/Pipeline/ConfiguredInstance.cs trunk/Source/StructureMap/Pipeline/IBuildInterceptor.cs trunk/Source/StructureMap/Pipeline/IBuildPolicy.cs trunk/Source/StructureMap/Pipeline/Instance.cs trunk/Source/StructureMap/Pipeline/SmartInstance.cs trunk/Source/StructureMap.AutoMocking/AutoMocker.cs trunk/Source/StructureMap.Testing/Configuration/DSL/ProfileExpressionTester.cs trunk/Source/StructureMap.Testing/Graph/DynamicInjectionTester.cs trunk/Source/StructureMap.Testing/ModelQueryTester.cs trunk/Source/StructureMap.Testing/ObjectFactoryInitializeTester.cs trunk/Source/StructureMap.Testing/StructureMap.Testing.dll.config Modified: trunk/Source/HTML/ConfiguringStructureMap.htm =================================================================== --- trunk/Source/HTML/ConfiguringStructureMap.htm 2008-10-23 23:02:07 UTC (rev 192) +++ trunk/Source/HTML/ConfiguringStructureMap.htm 2008-10-27 01:07:28 UTC (rev 193) @@ -15,14 +15,14 @@ else from the initial releases to StructureMap 2.5. You have three forms of configuration to choose from:</p> <ol> - <li>The Registry DSL</li> + <li>The Registry DSL -- The programmatic API for configuring the Container in code.</li> <li>Xml configuration (StructureMap.config, the App.config file, or named files)</li> - <li>StructureMap Attributes</li> + <li>StructureMap Attributes -- Not deprecated, but not really recommended either. </li> </ol> <p> The configuration is highly modular and you can mix and match configuration choices within the same Container instance. The strong recommendation is - to use the Registry DSL as much as possible, and use the Xml configuration + to use the Registry DSL as much as possible, then use the Xml configuration strictly for configuration that absolutely must be external to the code (connection strings, file paths, Url's, etc.). The attributes are deprecated and largely unnecessary now, but still supported for backwards @@ -42,89 +42,433 @@ <h4> Initializing the Container</h4> <p> - The recommended mechanism for initializing the Container is the Initialize() - method. The Initialize() method is a Nested Closure that acts against an - InitializationExpression object. The InitializationExpression has methods + The recommended mechanism for initializing the Container or ObjectFactory is the Initialize() + method. The Initialize() method is new for StructureMap 2.5, and largely + driven by (my current love affair with Lambda's) the confusion and misuse of + StructureMapConfiguration. StructureMapConfiguration is still supported, + but it is deprecated in the code and will be eliminated in a future release. Initialize() is a Nested Closure that + gives you a chance to express directives telling the Container how to construct + itself and add one or more sources of configuration. </p> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs20 \cf3 public\cf0 Container(\cf4 Action\cf0 <\cf4 ConfigurationExpression\cf0 > action)\par ?? \{\par ?? \cf3 var\cf0 expression = \cf3 new\cf0 \cf4 ConfigurationExpression\cf0 ();\par ?? action(expression);\par ??\par ?? construct(expression.BuildGraph());\par ?? \}} +--> +<div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> + <span style="overflow: scroll;"> + </span><span style="color: blue; overflow: scroll;">public Container(</span><span + style="color: #2b91af; overflow: scroll;">Action</span><span + style="overflow: scroll;"><</span><span + style="color: #2b91af; overflow: scroll;">ConfigurationExpression</span><span + style="overflow: scroll;">> action)</span></p> + <p style="margin: 0px;"> + <span style="overflow: scroll;"> {</span></p> + <p style="margin: 0px;"> + <span style="overflow: scroll;"> + </span><span style="color: blue; overflow: scroll;">var</span><span + style="overflow: scroll;"> expression = </span> + <span style="color: blue; overflow: scroll;">new</span><span + style="overflow: scroll;"> </span> + <span style="color: #2b91af; overflow: scroll;">ConfigurationExpression</span><span + style="overflow: scroll;">();</span></p> + <p style="margin: 0px;"> + <span style="overflow: scroll;"> + action(expression);</span></p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + <span style="overflow: scroll;"> + construct(expression.BuildGraph());</span></p> + <p style="margin: 0px;"> + <span style="overflow: scroll;"> }</span></p> +</div> +<!--EndFragment--> +</div> +<!--EndFragment--> +<p> + Typically, you would make a single call to the Initialize() method at + application start up (Global.asax for web application, or the main routine for a + desktop application). The Container (ObjectFactory is simply a static + wrapper around a single Container) is completely initialized and configured by + the Initialize() method in one atomic action. <b>Any successive calls to + Initialize() will effectively wipe out any existing configuration and + effectively restart the Container.</b> Here's a sample usage of + Initialize():</p> + +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red43\green145\blue175;\red0\green0\blue255;}??\fs20 \cf3 ObjectFactory\cf0 .Initialize(x =>\par ?? \{\par ?? x.UseDefaultStructureMapConfigFile = \cf4 true\cf0 ;\par ??\par ?? x.AddRegistry(\cf4 new\cf0 \cf3 CoreRegistry\cf0 ());\par ?? x.AddRegistry(\cf4 new\cf0 \cf3 SearchRegistry\cf0 ());\par ?? x.AddRegistry(\cf4 new\cf0 \cf3 WebCoreRegistry\cf0 ());\par ?? x.AddRegistry(\cf4 new\cf0 \cf3 WebRegistry\cf0 ());\par ?? x.AddRegistry(\cf4 new\cf0 \cf3 RuleRegistry\cf0 ());\par ?? \});} +--> +<div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> + <span style="overflow: scroll;"> + </span><span style="color: #2b91af; overflow: scroll;">ObjectFactory</span><span + style="overflow: scroll;">.Initialize(x =></span></p> + <p style="margin: 0px;"> + <span style="overflow: scroll;"> + {</span></p> + <p style="margin: 0px;"> + <span style="overflow: scroll;"> + x.UseDefaultStructureMapConfigFile = </span> + <span style="color: blue; overflow: scroll;">true</span><span + style="overflow: scroll;">;</span></p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + <span style="overflow: scroll;"> + x.AddRegistry(</span><span style="color: blue; overflow: scroll;">new</span><span + style="overflow: scroll;"> </span> + <span style="color: #2b91af; overflow: scroll;">CoreRegistry</span><span + style="overflow: scroll;">());</span></p> + <p style="margin: 0px;"> + <span style="overflow: scroll;"> + x.AddRegistry(</span><span style="color: blue; overflow: scroll;">new</span><span + style="overflow: scroll;"> </span> + <span style="color: #2b91af; overflow: scroll;">SearchRegistry</span><span + style="overflow: scroll;">());</span></p> + <p style="margin: 0px;"> + <span style="overflow: scroll;"> + x.AddRegistry(</span><span style="color: blue; overflow: scroll;">new</span><span + style="overflow: scroll;"> </span> + <span style="color: #2b91af; overflow: scroll;">WebCoreRegistry</span><span + style="overflow: scroll;">());</span></p> + <p style="margin: 0px;"> + <span style="overflow: scroll;"> + x.AddRegistry(</span><span style="color: blue; overflow: scroll;">new</span><span + style="overflow: scroll;"> </span> + <span style="color: #2b91af; overflow: scroll;">WebRegistry</span><span + style="overflow: scroll;">());</span></p> + <p style="margin: 0px;"> + <span style="overflow: scroll;"> + x.AddRegistry(</span><span style="color: blue; overflow: scroll;">new</span><span + style="overflow: scroll;"> </span> + <span style="color: #2b91af; overflow: scroll;">RuleRegistry</span><span + style="overflow: scroll;">());</span></p> + <p style="margin: 0px;"> + <span style="overflow: scroll;"> + });</span></p> +</div> +<!--EndFragment--> +<p> + Inside the Initialization() method you can declare directives against an + InitializationExpression object. The InitializationExpression object has + these methods for all all the possible configuration directives.</p> - <p> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;\red0\green128\blue0;}??\fs20 \cf3 public\cf0 \cf3 interface\cf0 \cf4 IInitializationExpression\par ??\cf0 \{\par ?? \cf5 // Directives on how to treat the StructureMap.config file\par ??\cf0 \cf3 bool\cf0 UseDefaultStructureMapConfigFile \{ \cf3 set\cf0 ; \}\par ?? \cf3 bool\cf0 IgnoreStructureMapConfig \{ \cf3 set\cf0 ; \}\par ??\par ?? \cf5 // Xml configuration from the App.Config file\par ??\cf0 \cf3 bool\cf0 PullConfigurationFromAppConfig \{ \cf3 set\cf0 ; \}\par ??\par ?? \cf5 // Ancillary sources of Xml configuration\par ??\cf0 \cf3 void\cf0 AddConfigurationFromXmlFile(\cf3 string\cf0 fileName);\par ?? \cf3 void\cf0 AddConfigurationFromNode(\cf4 XmlNode\cf0 node);\par ??\par ?? \cf5 // Specifying Registry's\par ??\cf0 \cf3 void\cf0 AddRegistry<T>() \cf3 where\cf0 T : \cf4 Registry\cf0 , \cf3 new\cf0 ();\par ?? \cf3 void\cf0 AddRegistry(\cf4 Registry\cf0 registry);\par ??\par ?? \cf5 // Designate the Default Profile. This will be applied as soon as the \par ??\cf0 \cf5 // Container is initialized.\par ??\cf0 \cf3 string\cf0 DefaultProfileName \{ \cf3 get\cf0 ; \cf3 set\cf0 ; \}\par ??\par ?? \cf5 // ... and the Registry DSL as well\par ??\par ??\cf0 \cf5 // The Registry DSL\par ??\cf0 \cf4 CreatePluginFamilyExpression\cf0 <PLUGINTYPE> BuildInstancesOf<PLUGINTYPE>();\par ?? \cf4 CreatePluginFamilyExpression\cf0 <PLUGINTYPE> ForRequestedType<PLUGINTYPE>();\par ?? \cf4 GenericFamilyExpression\cf0 ForRequestedType(\cf4 Type\cf0 pluginType);\par ?? \cf4 Registry\cf0 .\cf4 BuildWithExpression\cf0 <T> ForConcreteType<T>();\par ??\par ?? \cf4 IsExpression\cf0 <T> InstanceOf<T>();\par ?? \cf4 GenericIsExpression\cf0 InstanceOf(\cf4 Type\cf0 pluginType);\par ??\par ?? \cf4 ProfileExpression\cf0 CreateProfile(\cf3 string\cf0 profileName);\par ?? \cf3 void\cf0 CreateProfile(\cf3 string\cf0 profileName, \cf4 Action\cf0 <\cf4 ProfileExpression\cf0 > action);\par ??\par ?? \cf3 void\cf0 RegisterInterceptor(\cf4 TypeInterceptor\cf0 interceptor);\par ?? \cf4 MatchedTypeInterceptor\cf0 IfTypeMatches(\cf4 Predicate\cf0 <\cf4 Type\cf0 > match);\par ??\par ?? \cf3 void\cf0 Scan(\cf4 Action\cf0 <\cf4 IAssemblyScanner\cf0 > action);\par ??\par ?? \cf4 CreatePluginFamilyExpression\cf0 <PLUGINTYPE> FillAllPropertiesOfType<PLUGINTYPE>();\par ?? \}} +--> +<div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> </p> - <p> + <p style="margin: 0px;"> + <span style="overflow: scroll;"> </span> + <span style="color: blue; overflow: scroll;">public</span><span + style="overflow: scroll;"> </span> + <span style="color: blue; overflow: scroll;">interface</span><span + style="overflow: scroll;"> </span> + <span style="color: #2b91af; overflow: scroll;">IInitializationExpression</span></p> + <p style="margin: 0px;"> + <span style="overflow: scroll;"> {</span></p> + <p style="margin: 0px;"> + <span style="overflow: scroll;"> + </span><span style="color: green; overflow: scroll;">// Directives on how to + treat the StructureMap.config file</span></p> + <p style="margin: 0px;"> + <span style="overflow: scroll;"> + </span><span style="color: blue; overflow: scroll;">bool</span><span + style="overflow: scroll;"> UseDefaultStructureMapConfigFile { </span> + <span style="color: blue; overflow: scroll;">set</span><span + style="overflow: scroll;">; }</span></p> + <p style="margin: 0px;"> + <span style="overflow: scroll;"> + </span><span style="color: blue; overflow: scroll;">bool</span><span + style="overflow: scroll;"> IgnoreStructureMapConfig { </span> + <span style="color: blue; overflow: scroll;">set</span><span + style="overflow: scroll;">; }</span></p> + <p style="margin: 0px;"> </p> - <p> + <p style="margin: 0px;"> + <span style="overflow: scroll;"> + </span><span style="color: green; overflow: scroll;">// Xml configuration from + the App.Config file</span></p> + <p style="margin: 0px;"> + <span style="overflow: scroll;"> + </span><span style="color: blue; overflow: scroll;">bool</span><span + style="overflow: scroll;"> PullConfigurationFromAppConfig { </span> + <span style="color: blue; overflow: scroll;">set</span><span + style="overflow: scroll;">; }</span></p> + <p style="margin: 0px;"> </p> - <p> + <p style="margin: 0px;"> + <span style="overflow: scroll;"> + </span><span style="color: green; overflow: scroll;">// Ancillary sources of Xml + configuration</span></p> + <p style="margin: 0px;"> + <span style="overflow: scroll;"> + </span><span style="color: blue; overflow: scroll;">void</span><span + style="overflow: scroll;"> AddConfigurationFromXmlFile(</span><span + style="color: blue; overflow: scroll;">string</span><span + style="overflow: scroll;"> fileName);</span></p> + <p style="margin: 0px;"> + <span style="overflow: scroll;"> + </span><span style="color: blue; overflow: scroll;">void</span><span + style="overflow: scroll;"> AddConfigurationFromNode(</span><span + style="color: #2b91af; overflow: scroll;">XmlNode</span><span + style="overflow: scroll;"> node);</span></p> + <p style="margin: 0px;"> </p> - <h4> - Using a Bootstrapper</h4> - <p> + <p style="margin: 0px;"> + <span style="overflow: scroll;"> + </span><span style="color: green; overflow: scroll;">// Specifying Registry's</span></p> + <p style="margin: 0px;"> + <span style="overflow: scroll;"> + </span><span style="color: blue; overflow: scroll;">void</span><span + style="overflow: scroll;"> AddRegistry<T>() </span> + <span style="color: blue; overflow: scroll;">where</span><span + style="overflow: scroll;"> T : </span> + <span style="color: #2b91af; overflow: scroll;">Registry</span><span + style="overflow: scroll;">, </span> + <span style="color: blue; overflow: scroll;">new</span><span + style="overflow: scroll;">();</span></p> + <p style="margin: 0px;"> + <span style="overflow: scroll;"> + </span><span style="color: blue; overflow: scroll;">void</span><span + style="overflow: scroll;"> AddRegistry(</span><span + style="color: #2b91af; overflow: scroll;">Registry</span><span + style="overflow: scroll;"> registry);</span></p> + <p style="margin: 0px;"> </p> - <p> + <p style="margin: 0px;"> + <span style="overflow: scroll;"> + </span><span style="color: green; overflow: scroll;">// Designate the Default + Profile. This will be applied as soon as the </span> + </p> + <p style="margin: 0px;"> + <span style="overflow: scroll;"> + </span><span style="color: green; overflow: scroll;">// Container is + initialized.</span></p> + <p style="margin: 0px;"> + <span style="overflow: scroll;"> + </span><span style="color: blue; overflow: scroll;">string</span><span + style="overflow: scroll;"> DefaultProfileName { </span> + <span style="color: blue; overflow: scroll;">get</span><span + style="overflow: scroll;">; </span> + <span style="color: blue; overflow: scroll;">set</span><span + style="overflow: scroll;">; }</span></p> + <p style="margin: 0px;"> </p> - <h4> - The StructureMap.config File</h4> - <p> - Historically, StructureMap looked for all of its configuration in a file named - "StructureMap.config" file in the ApplicationBase folder. By default, if - the StructureMap.config file is found in the ApplicationBase folder, the Xml - configuration from StructureMap.config will be applied to the internal container - of ObjectFactory. Technically, you could still do all configuration in the - StructureMap.config file. In this case, the StructureMap.config file would - be read and applied in the first call to any of the ObjectFactory methods that - request services. Likewise, StructureMap will not throw any exceptions if - the StructureMap.config file cannot be found.</p> - <p> - The default behavior can be overriden. First, if you are using the - StructureMap.config file, you might want to make the existence of this file - mandatory to prevent odd problems from missing configuration:</p> + <p style="margin: 0px;"> + <span style="overflow: scroll;"> + </span><span style="color: green; overflow: scroll;">// ... and the Registry DSL + as well</span></p> + <p style="margin: 0px;"> + <span style="overflow: scroll;"> }</span></p> + <p style="margin: 0px;"> + </p> +</div> +<!--EndFragment--> +<p> + </p> +<h4> + Adding Configuration to an Existing Container</h4> +<p> + In contrast to Initialize(), the Configure() method allows you to add additional + configuration to an existing Container or ObjectFactory. Think of this + scenario. You're building a composite application that contains multiple + modules spread over several assemblies, but you might not want to load any of + the configuration or types for a particular module until it's requested by the + user. In that case, you can use the Configure() method like this:</p> <!-- -{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green128\blue0;\red43\green145\blue175;\red0\green0\blue255;}??\fs20 \cf3 // This code enforces the existence of the StructureMap.config file\par ??\cf0 \cf3 // Initialize() will throw an exception if the StructureMap.config file\par ??\cf0 \cf3 // cannot be found\par ??\cf0 \cf4 ObjectFactory\cf0 .Initialize(x =>\par ?? \{\par ?? x.UseDefaultStructureMapConfigFile = \cf5 true\cf0 ;\par ?? \});} +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green128\blue0;\red43\green145\blue175;\red163\green21\blue21;}??\fs20 \cf3 // This code would add any configuration from\par ??\cf0 \cf3 // Registry classes found in the \par ??\cf0 \cf3 // assembly named 'MyApplication.Module1'\par ??\cf0 \cf4 ObjectFactory\cf0 .Configure(x =>\par ?? \{\par ?? x.Scan(scan =>\par ?? \{\par ?? scan.LookForRegistries();\par ?? scan.Assembly(\cf5 "MyApplication.Module1"\cf0 );\par ?? \});\par ?? \});} --> -<div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> +<div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid; overflow: scroll;"> <p style="margin: 0px;"> - <span style="color: green;">// This code enforces the existence of the - StructureMap.config file</span></p> + <span style="color: green;">// This code would add any configuration from</span></p> <p style="margin: 0px;"> - <span style="color: green;">// Initialize() will throw an exception if the - StructureMap.config file</span></p> + <span style="color: green;">// Registry classes found in the </span> + </p> <p style="margin: 0px;"> - <span style="color: green;">// cannot be found</span></p> + <span style="color: green;">// assembly named 'MyApplication.Module1'</span></p> <p style="margin: 0px;"> - <span style="color: #2b91af;">ObjectFactory</span>.Initialize(x =></p> + <span style="color: #2b91af;">ObjectFactory</span>.Configure(x =></p> <p style="margin: 0px;"> {</p> <p style="margin: 0px;"> - x.UseDefaultStructureMapConfigFile = <span style="color: blue;">true</span>;</p> + x.Scan(scan =></p> <p style="margin: 0px;"> + + {</p> + <p style="margin: 0px;"> + + scan.LookForRegistries();</p> + <p style="margin: 0px;"> + + scan.Assembly(<span style="color: #a31515;">"MyApplication.Module1"</span>);</p> + <p style="margin: 0px;"> + + });</p> + <p style="margin: 0px;"> });</p> </div> <!--EndFragment--> <p> - You can also specifically ignore the StructureMap.config file at initialization - time so that the StructureMap.config file will never be used:</p> + To summarize, Initialize() completely resets the configuration of a Container, + and Configure() is purely additive. If Configure() should happen to be + called before Initialize(), it will set up the Container with the configuration + in the Configure() call. Configure() offers a subset of the Initialize() + method (it leaves out the directives for the StructureMap.config file), and it + also includes the entire Registry DSL. You can take advantage of that fact + to add a few types or instances at a time:</p> <!-- -{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red43\green145\blue175;\red0\green0\blue255;\red163\green21\blue21;}??\fs20 \cf3 ObjectFactory\cf0 .Initialize(x =>\par ?? \{\par ?? x.IgnoreStructureMapConfig = \cf4 true\cf0 ;\par ?? \par ?? x.ForRequestedType<\cf3 IWidget\cf0 >().TheDefault.Is\par ?? .OfConcreteType<\cf3 DoctorTester\cf0 .\cf3 NumberWidget\cf0 >()\par ?? .WithCtorArg(\cf5 "age"\cf0 ).EqualToAppSetting(\cf5 "age"\cf0 );\par ?? \});} +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red43\green145\blue175;}??\fs20 \par ?? \cf3 ObjectFactory\cf0 .Configure(x =>\par ?? \{\par ?? x.ForRequestedType<\cf3 ISomething\cf0 >().TheDefaultIsConcreteType<\cf3 SomethingOne\cf0 >();\par ?? \});\par ??} --> -<div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> +<div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid; overflow: scroll;"> <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> - <span style="color: #2b91af;">ObjectFactory</span>.Initialize(x =></p> + <span style="color: #2b91af;">ObjectFactory</span>.Configure(x =></p> <p style="margin: 0px;"> {</p> <p style="margin: 0px;"> - x.IgnoreStructureMapConfig = <span style="color: blue;">true</span>;</p> + x.ForRequestedType<<span style="color: #2b91af;">ISomething</span>>().TheDefaultIsConcreteType<<span + style="color: #2b91af;">SomethingOne</span>>();</p> <p style="margin: 0px;"> });</p> </div> <!--EndFragment--> <p> - </p> + </p> <p> + </p> +<p> + </p> +<h4> + Using the App.Config File</h4> +<p> + The <a href="http://msdn.microsoft.com/en-us/library/system.configuration.aspx"> + System.Configuration</a> namespace in the .Net framework provides a lot of + functionality for caching and encrypting configuration. To take advantage + of this functionality StructureMap offers an option to embed configuration + directly into the App.config file (web.config for web development). Just + add a section for StructureMap like this:</p> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue255;\red255\green255\blue255;\red163\green21\blue21;\red255\green0\blue0;\red0\green0\blue0;\red0\green128\blue0;}??\fs20 \cf1 <?\cf3 xml\cf1 \cf4 version\cf1 =\cf0 "\cf1 1.0\cf0 "\cf1 \cf4 encoding\cf1 =\cf0 "\cf1 utf-8\cf0 "\cf1 ?>\par ??<\cf3 configuration\cf1 >\par ?? <\cf3 configSections\cf1 >\par ?? <\cf3 section\cf1 \cf4 name\cf1 =\cf0 "\cf1 StructureMap\cf0 "\cf1 \cf4 type\cf1 =\cf0 "\cf1 StructureMap.Configuration.StructureMapConfigurationSection,StructureMap\cf0 "\cf1 />\par ?? </\cf3 configSections\cf1 >\par ??\par ?? <\cf3 StructureMap\cf1 >\par ?? <!--\cf6 Put StructureMap configuration here \cf1 -->\par ?? \par ?? <\cf3 Assembly\cf1 \cf4 Name\cf1 =\cf0 "\cf1 StructureMap.Testing.GenericWidgets\cf0 "\cf1 />\par ??\par ?? <\cf3 PluginFamily\cf1 \cf4 Assembly\cf1 =\cf0 "\cf1 StructureMap.Testing.GenericWidgets\cf0 "\cf1 \cf4 Type\cf1 =\cf0 "\cf1 StructureMap.Testing.GenericWidgets.IThing`2\cf0 "\cf1 \cf4 DefaultKey\cf1 =\cf0 "\cf1 Cornflower\cf0 "\cf1 >\par ?? <\cf3 Plugin\cf1 \cf4 Assembly\cf1 =\cf0 "\cf1 StructureMap.Testing.GenericWidgets\cf0 "\cf1 \cf4 Type\cf1 =\cf0 "\cf1 StructureMap.Testing.GenericWidgets.ColorThing`2\cf0 "\cf1 \cf4 ConcreteKey\cf1 =\cf0 "\cf1 Color\cf0 "\cf1 />\par ?? <\cf3 Plugin\cf1 \cf4 Assembly\cf1 =\cf0 "\cf1 StructureMap.Testing.GenericWidgets\cf0 "\cf1 \cf4 Type\cf1 =\cf0 "\cf1 StructureMap.Testing.GenericWidgets.ComplexThing`2\cf0 "\cf1 \cf4 ConcreteKey\cf1 =\cf0 "\cf1 Complex\cf0 "\cf1 />\par ??\par ?? <\cf3 Instance\cf1 \cf4 Key\cf1 =\cf0 "\cf1 Cornflower\cf0 "\cf1 \cf4 Type\cf1 =\cf0 "\cf1 Color\cf0 "\cf1 >\par ?? <\cf3 Property\cf1 \cf4 Name\cf1 =\cf0 "\cf1 color\cf0 "\cf1 \cf4 Value\cf1 =\cf0 "\cf1 Cornflower\cf0 "\cf1 />\par ?? </\cf3 Instance\cf1 >\par ??\par ?? <\cf3 Instance\cf1 \cf4 Key\cf1 =\cf0 "\cf1 Complicated\cf0 "\cf1 \cf4 Type\cf1 =\cf0 "\cf1 Complex\cf0 "\cf1 >\par ?? <\cf3 Property\cf1 \cf4 Name\cf1 =\cf0 "\cf1 name\cf0 "\cf1 \cf4 Value\cf1 =\cf0 "\cf1 Jeremy\cf0 "\cf1 />\par ?? <\cf3 Property\cf1 \cf4 Name\cf1 =\cf0 "\cf1 age\cf0 "\cf1 \cf4 Value\cf1 =\cf0 "\cf1 32\cf0 "\cf1 />\par ?? <\cf3 Property\cf1 \cf4 Name\cf1 =\cf0 "\cf1 ready\cf0 "\cf1 \cf4 Value\cf1 =\cf0 "\cf1 true\cf0 "\cf1 />\par ?? </\cf3 Instance\cf1 >\par ?? </\cf3 PluginFamily\cf1 >\par ??\par ?? <\cf3 PluginFamily\cf1 \cf4 Assembly\cf1 =\cf0 "\cf1 StructureMap.Testing.GenericWidgets\cf0 "\cf1 \cf4 Type\cf1 =\cf0 "\cf1 StructureMap.Testing.GenericWidgets.ISimpleThing`1\cf0 "\cf1 \cf4 DefaultKey\cf1 =\cf0 "\cf1 Simple\cf0 "\cf1 >\par ?? <\cf3 Plugin\cf1 \cf4 Assembly\cf1 =\cf0 "\cf1 StructureMap.Testing.GenericWidgets\cf0 "\cf1 \cf4 Type\cf1 =\cf0 "\cf1 StructureMap.Testing.GenericWidgets.SimpleThing`1\cf0 "\cf1 \cf4 ConcreteKey\cf1 =\cf0 "\cf1 Simple\cf0 "\cf1 />\par ?? </\cf3 PluginFamily\cf1 >\par ?? </\cf3 StructureMap\cf1 >\par ?? \par ?? \par ?? <\cf3 appSettings\cf1 >\par ?? <\cf3 add\cf1 \cf4 key\cf1 =\cf0 "\cf1 Color\cf0 "\cf1 \cf4 value\cf1 =\cf0 "\cf1 Blue\cf0 "\cf1 />\par ?? <\cf3 add\cf1 \cf4 key\cf1 =\cf0 "\cf1 Day\cf0 "\cf1 \cf4 value\cf1 =\cf0 "\cf1 Monday\cf0 "\cf1 />\par ?? </\cf3 appSettings\cf1 >\par ??\par ??\par ??</\cf3 configuration\cf1 >} +--> +<div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid; overflow: scroll;"> + <p style="margin: 0px;"> + <span style="color: blue;"><?</span><span style="color: #a31515;">xml</span><span + style="color: blue;"> </span><span style="color: red;">version</span><span + style="color: blue;">=</span>"<span style="color: blue;">1.0</span>"<span + style="color: blue;"> </span><span style="color: red;">encoding</span><span + style="color: blue;">=</span>"<span style="color: blue;">utf-8</span>"<span + style="color: blue;"> ?></span></p> + <p style="margin: 0px;"> + <span style="color: blue;"><</span><span style="color: #a31515;">configuration</span><span + style="color: blue;">></span></p> + <p style="margin: 0px;"> + <span style="color: blue;"> <</span><span style="color: #a31515;">configSections</span><span + style="color: blue;">></span></p> + <p style="margin: 0px;"> + <span style="color: blue;"> <</span><span + style="color: #a31515;">section</span><span style="color: blue;"> </span> + <span style="color: red;">name</span><span style="color: blue;">=</span>"<span + style="color: blue;">StructureMap</span>"<span style="color: blue;"> </span> + <span style="color: red;">type</span><span style="color: blue;">=</span>"<span + style="color: blue;">StructureMap.Configuration.StructureMapConfigurationSection,StructureMap</span>"<span + style="color: blue;">/></span></p> + <p style="margin: 0px;"> + <span style="color: blue;"> </</span><span style="color: #a31515;">configSections</span><span + style="color: blue;">></span></p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + <span style="color: blue;"> <</span><span style="color: #a31515;">StructureMap</span><span + style="color: blue;">></span></p> + <p style="margin: 0px;"> + <span style="color: blue;"> <!--</span><span + style="color: green;"> Put StructureMap configuration here </span> + <span style="color: blue;">--></span></p> + <p style="margin: 0px;"> + <span style="color: blue;"> </</span><span style="color: #a31515;">StructureMap</span><span + style="color: blue;">></span></p> + <p style="margin: 0px;"> + <span style="color: blue;"></</span><span style="color: #a31515;">configuration</span><span + style="color: blue;">></span></p> +</div> +<!--EndFragment--> +<p> + Then you need to explicitly tell ObjectFactory to use this configuration:</p> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red43\green145\blue175;\red0\green0\blue255;\red0\green128\blue0;}??\fs20 \cf3 ObjectFactory\cf0 .Initialize(x =>\par ?? \{\par ?? x.UseDefaultStructureMapConfigFile = \cf4 false\cf0 ;\par ??\par ?? \cf5 // Tell StructureMap to look for configuration \par ??\cf0 \cf5 // from the App.config file\par ??\cf0 \cf5 // The default is false\par ??\cf0 x.PullConfigurationFromAppConfig = \cf4 true\cf0 ;\par ?? \});} +--> +<div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid; overflow: scroll;"> + <p style="margin: 0px;"> + + <span style="color: #2b91af;">ObjectFactory</span>.Initialize(x =></p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + + <span style="color: green;">// Tell StructureMap to look for configuration </span> + </p> + <p style="margin: 0px;"> + + <span style="color: green;">// from the App.config file</span></p> + <p style="margin: 0px;"> + + <span style="color: green;">// The default is false</span></p> + <p style="margin: 0px;"> + + x.PullConfigurationFromAppConfig = <span style="color: blue;">true</span>;</p> + <p style="margin: 0px;"> +& });</p> +</div> +<!--EndFragment--> +<p> + </p> +<h4> + The StructureMap.config File</h4> +<p>In the beginning, StructureMap configuration began and ended with a single file named "StructureMap.config" in the application base folder that contained StructureMap Xml configuration (in short, wherever your App.config file would go). Today, the default behavior is that StructureMap will automatically read in configuration data from the StructureMap.config if it is found when either ObjectFactory.Initialize() is called, or the first time that a service is requested from ObjectFactory. You can technically use only the StructureMap.config file and completely forgo the the usage of any programmatic bootstrapping./p> + +<p>You can override the default behavior for the StructureMap.config file. If you want to make the StructureMap.config file mandatory, you can do this:</p> + <!-- +{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red43\green145\blue175;\red0\green128\blue0;\red0\green0\blue255;}??\fs20 \cf3 ObjectFactory\cf0 .Initialize(x =>\par ?? \{\par ?? \cf4 // We put the properties for an NHibernate ISession\par ??\cf0 \cf4 // in the StructureMap.config file, so this file\par ??\cf0 \cf4 // must be there for our application to \par ??\cf0 \cf4 // function correctly\par ??\cf0 x.UseDefaultStructureMapConfigFile = \cf5 true\cf0 ;\par ??\par ?? x.AddRegistry(\cf5 new\cf0 \cf3 CoreRegistry\cf0 ());\par ?? x.AddRegistry(\cf5 new\cf0 \cf3 SearchRegistry\cf0 ());\par ?? x.AddRegistry(\cf5 new\cf0 \cf3 WebCoreRegistry\cf0 ());\par ?? x.AddRegistry(\cf5 new\cf0 \cf3 WebRegistry\cf0 ());\par ?? x.AddRegistry(\cf5 new\cf0 \cf3 RuleRegistry\cf0 ());\par ?? \});} +--> <div style="border: thin solid black; background: white none repeat scroll 0% 0%; font-size: 10pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; color: black; font-family: courier new;"> +<p style="margin: 0px;"><span style="overflow: scroll;"> </span><span style="overflow: scroll; color: rgb(43, 145, 175);">ObjectFactory</span><span style="overflow: scroll;">.Initialize(x =></span></p> + +<p style="margin: 0px;"><span style="overflow: scroll;"> {</span></p> + +<p style="margin: 0px;"><span style="overflow: scroll;"> </span><span style="overflow: scroll; color: green;">// We put the properties for an NHibernate ISession</span></p> + +<p style="margin: 0px;"><span style="overflow: scroll;"> </span><span style="overflow: scroll; color: green;">// in the StructureMap.config file, so this file</span></p> + +<p style="margin: 0px;"><span style="overflow: scroll;"> </span><span style="overflow: scroll; color: green;">// must be there for our application to </span></p> + +<p style="margin: 0px;"><span style="overflow: scroll;"> </span><span style="overflow: scroll; color: green;">// function correctly</span></p> + +<p style="margin: 0px;"><span style="overflow: scroll;"> x.UseDefaultStructureMapConfigFile = </span><span style="overflow: scroll; color: blue;">true</span><span style="overflow: scroll;">;</span></p> + +<p style="margin: 0px;"><span style="overflow: scroll;"> });</span></p> + </div> <!--EndFragment--> +<p>At other times you might want to force ObjectFactory to ignore the StructureMap.config file even if it does exist.</p> + <!-- +{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red43\green145\blue175;\red0\green0\blue255;\red163\green21\blue21;}??\fs20 \cf3 ObjectFactory\cf0 .Initialize(x =>\par ?? \{\par ?? x.IgnoreStructureMapConfig = \cf4 true\cf0 ;\par ?? \par ?? x.ForRequestedType<\cf3 IWidget\cf0 >().TheDefault.Is\par ?? .OfConcreteType<\cf3 DoctorTester\cf0 .\cf3 NumberWidget\cf0 >()\par ?? .WithCtorArg(\cf5 "age"\cf0 ).EqualToAppSetting(\cf5 "age"\cf0 );\par ?? \});} +--> <div style="border: thin solid black; background: white none repeat scroll 0% 0%; font-size: 10pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; color: black; font-family: courier new;"> +<p style="margin: 0px;"><span style="overflow: scroll;"> </span><span style="overflow: scroll; color: rgb(43, 145, 175);">ObjectFactory</span><span style="overflow: scroll;">.Initialize(x =></span></p> + +<p style="margin: 0px;"><span style="overflow: scroll;"> {</span></p> + +<p style="margin: 0px;"><span style="overflow: scroll;"> x.IgnoreStructureMapConfig = </span><span style="overflow: scroll; color: blue;">true</span><span style="overflow: scroll;">;</span></p> + +<p style="margin: 0px;"><span style="overflow: scroll;">& });</span></p> + </div> <!--EndFragment--><p> + </p> +<p> </p> <p> </p> @@ -147,7 +491,7 @@ {</p> <p style="margin: 0px;"> - <span style="color: #2b91af;">ObjectFactory</span>.Initialize(x =></p> + <span style="color: #2b91af;">ObjectFactory</span>.Initialize(x =>/p> <p style="margin: 0px;"> {</p> <p style="margin: 0px;"> @@ -195,74 +539,14 @@ <p style="margin: 0px"> </p> <p style="margin: 0px"> - </p> + & </p> <p style="margin: 0px"> </p> <h4 style="margin: 0px"> - Adding Configuration to a Container after Initialization</h4> + Using Container independent of ObjectFactory/h4> <p style="margin: 0px"> </p> <p style="margin: 0px"> - Sometimes you may want to add additional types and Instances to an existing - container. The Configure() method on both ObjectFactory and IContainer is - used for this purpose. - </p> - <p style="margin: 0px"> - </p> - <p style="margin: 0px"> - Here's a scenario. You're building a composite desktop application, and - for performance reasons you want to delay loading the screens and features for a - module of the application until the user explicitly activates that module. - When the user decides to start using that module, your code needs to immediately - add more types and Instances to the already running ObjectFactory. The - following code would search an assembly named - "MyCompany.MyApp.ExtensionAssembly" for Registry classes. The - configuration embedded in these new Registry classes would be added to the - Container internal to ObjectFactory.</p> - <p style="margin: 0px"> - </p> -<!-- -{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green128\blue0;\red43\green145\blue175;\red163\green21\blue21;}??\fs20 \cf3 // Adding configuration from an extension Assembly\par ??\cf0 \cf3 // after ObjectFactory is already configured\par ??\cf0 \cf4 ObjectFactory\cf0 .Configure(x =>\par ?? \{\par ?? x.Scan(scan =>\par ?? \{\par ?? scan.Assembly(\cf5 "MyCompany.MyApp.ExtensionAssembly"\cf0 );\par ?? scan.LookForRegistries();\par ?? \});\par ?? \});} ---> - <div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> - <p style="margin: 0px;"> - - <span style="color: green;">// Adding configuration from an extension Assembly</span></p> - <p style="margin: 0px;"> - - <span style="color: green;">// after ObjectFactory is already configured</span></p> - <p style="margin: 0px;"> - - <span style="color: #2b91af;">ObjectFactory</span>.Configure(x =></p> - <p style="margin: 0px;"> - {</p> - <p style="margin: 0px;"> - - x.Scan(scan =></p> - <p style="margin: 0px;"> - {</p> - <p style="margin: 0px;"> - - scan.Assembly(<span style="color: #a31515;">"MyCompany.MyApp.ExtensionAssembly"</span>);</p> - <p style="margin: 0px;"> - - scan.LookForRegistries();</p> - <p style="margin: 0px;"> - - });</p> - <p style="margin: 0px;"> - });</p> - </div> -<!--EndFragment--> -<p style="margin: 0px"> - </p> - <p style="margin: 0px"> - </p> - <h4 style="margin: 0px"> - Using Container independent of ObjectFactory</h4> - <p style="margin: 0px"> - </p> - <p style="margin: 0px"> New to 2.5 is the ability to create an instance of the underlying Container class independent of the static ObjectFactory class (actually, you always could do this, but it's much easier in 2.5). The IContainer interface has @@ -454,101 +738,13 @@ <p style="margin: 0px"> </p> <p style="margin: 0px"> - </p> -<p> - </p> -<!-- -{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;\red0\green128\blue0;}??\fs20 \cf3 public\cf0 \cf3 class\cf0 \cf4 WebCoreRegistry\cf0 : \cf4 Registry\par ??\cf0 \{\par ?? \cf3 public\cf0 WebCoreRegistry()\par ?? \{\par ?? \cf5 // This is used as a sort of lightweight ScriptManager in\par ??\cf0 \cf5 // our website application\par ??\cf0 ForRequestedType<\cf4 ICachedSet\cf0 >().TheDefaultIsConcreteType<\cf4 CachedSet\cf0 >()\par ?? .CacheBy(\cf4 InstanceScope\cf0 .Hybrid);\par ??\par ?? ForRequestedType<\cf4 IControlBuilder\cf0 >().TheDefault.Is.OfConcreteType<\cf4 AspNetControlBuilder\cf0 >();\par ?? ForRequestedType<\cf4 IPartialRenderer\cf0 >().TheDefault.Is.OfConcreteType<\cf4 PartialRenderer\cf0 >();\par ??\par ?? Scan(x =>\par ?? \{\par ?? \cf5 // Scan "this" assembly. In other words, the assembly that \par ??\cf0 \cf5 // contains the WebCoreRegistry class\par ??\cf0 x.TheCallingAssembly();\par ??\par ?? x.IncludeNamespaceContainingType<\cf4 AuthenticationContext\cf0 >();\par ?? x.IncludeNamespaceContainingType<\cf4 ISecurityDataService\cf0 >();\par ??\par ?? x.WithDefaultConventions();\par ?? \});\par ?? \}\par ?? \}} ---> -<div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> - <p style="margin: 0px;"> - <span style="color: blue;">public</span> <span style="color: blue;"> - class</span> <span style="color: #2b91af;">WebCoreRegistry</span> : - <span style="color: #2b91af;">Registry</span></p> - <p style="margin: 0px;"> - {</p> - <p style="margin: 0px;"> - <span style="color: blue;">public</span> - WebCoreRegistry()</p> - <p style="margin: 0px;"> - {</p> - <p style="margin: 0px;"> - - <span style="color: green;">// This is used as a sort of lightweight - ScriptManager in</span></p> - <p style="margin: 0px;"> - - <span style="color: green;">// our website application</span></p> - <p style="margin: 0px;"> - ForRequestedType<<span - style="color: #2b91af;">ICachedSet</span>>().TheDefaultIsConcreteType<<span - style="color: #2b91af;">CachedSet</span>>()</p> - <p style="margin: 0px;"> - - .CacheBy(<span style="color: #2b91af;">InstanceScope</span>.Hybrid);</p> - <p style="margin: 0px;"> - </p> - <p style="margin: 0px;"> - ForRequestedType<<span - style="color: #2b91af;">IControlBuilder</span>>().TheDefault.Is.OfConcreteType<<span - style="color: #2b91af;">AspNetControlBuilder</span>>();</p> - <p style="margin: 0px;"> - ForRequestedType<<span - style="color: #2b91af;">IPartialRenderer</span>>().TheDefault.Is.OfConcreteType<<span - style="color: #2b91af;">PartialRenderer</span>>();</p> - <p style="margin: 0px;"> - </p> - <p style="margin: 0px;"> - Scan(x =></p> - <p style="margin: 0px;"> - {</p> - <p style="margin: 0px;"> - - <span style="color: green;">// Scan "this" assembly. In other words, the - assembly that </span> - </p> - <p style="margin: 0px;"> - - <span style="color: green;">// contains the WebCoreRegistry class</span></p> - <p style="margin: 0px;"> - - x.TheCallingAssembly();</p> - <p style="margin: 0px;"> - </p> - <p style="margin: 0px;"> - - x.IncludeNamespaceContainingType<<span style="color: #2b91af;">AuthenticationContext</span>>();</p> - <p style="margin: 0px;"> - - x.IncludeNamespaceContainingType<<span style="color: #2b91af;">ISecurityDataService</span>>();</p> - <p style="margin: 0px;"> - </p> - <p style="margin: 0px;"> - - x.WithDefaultConventions();</p> - <p style="margin: 0px;"> - });</p> - <p style="margin: 0px;"> - }</p> - <p style="margin: 0px;"> - }</p> -</div> -<!--EndFragment--> -<p> - </p> -<h4> - </h4> + & </p> <p style="margin: 0px"> </p> -<p style="margin: 0px"> - </p> -<p style="margin: 0px"> - </p> <h4 style="margin: 0px"> </h4> <h4 style="margin: 0px"> - StructureMapConfiguration/h4> - <p style="margin: 0px"> + StructureMapConfigurationp style="margin: 0px"> </p> <p style="margin: 0px"> </p> Modified: trunk/Source/StructureMap/Configuration/DSL/Expressions/CreatePluginFamilyExpression.cs =================================================================== --- trunk/Source/StructureMap/Configuration/DSL/Expressions/CreatePluginFamilyExpression.cs 2008-10-23 23:02:07 UTC (rev 192) +++ trunk/Source/StructureMap/Configuration/DSL/Expressions/CreatePluginFamilyExpression.cs 2008-10-27 01:07:28 UTC (rev 193) @@ -8,7 +8,8 @@ namespace StructureMap.Configuration.DSL.Expressions { /// <summary> - /// Represents the parameters for creating instances of a given Type + /// Expression Builder that has grammars for defining policies at the + /// PluginType level /// </summary> public class CreatePluginFamilyExpression<PLUGINTYPE> { @@ -29,11 +30,19 @@ }); } + /// <summary> + /// Define the Default Instance for this PluginType + /// </summary> public IsExpression<PLUGINTYPE> TheDefault { get { return new InstanceExpression<PLUGINTYPE>(i => registerDefault(i)); } } + /// <summary> + /// Add multiple Instance's to this PluginType + /// </summary> + /// <param name="action"></param> + /// <returns></returns> public CreatePluginFamilyExpression<PLUGINTYPE> AddInstances(Action<IInstanceExpression<PLUGINTYPE>> action) { var list = new List<Instance>(); @@ -108,7 +117,12 @@ return this; } - + /// <summary> + /// Register an Action to run against any object of this PluginType immediately after + /// it is created, but before the new object is passed back to the caller + /// </summary> + /// <param name="handler"></param> + /// <returns></returns> public CreatePluginFamilyExpression<PLUGINTYPE> OnCreation(Action<PLUGINTYPE> handler) { _children.Add( @@ -127,6 +141,14 @@ return this; } + /// <summary> + /// Register a Func to run against any object of this PluginType immediately after it is created, + /// but before the new object is passed back to the caller. Unlike <see cref="OnCreation">OnCreation()</see>, + /// EnrichWith() gives the the ability to return a different object. Use this method for runtime AOP + /// scenarios or to return a decorator. + /// </summary> + /// <param name="handler"></param> + /// <returns></returns> public CreatePluginFamilyExpression<PLUGINTYPE> EnrichWith(EnrichmentHandler<PLUGINTYPE> handler) { _children.Add( @@ -141,9 +163,20 @@ return this; } - + /// <summary> + /// Shortcut method to add an additional Instance to this Plugin Type + /// as just a Concrete Type. This will only work if the Concrete Type + /// has no primitive constructor or mandatory Setter arguments. + /// </summary> + /// <typeparam name="PLUGGEDTYPE"></typeparam> + /// <returns></returns> public CreatePluginFamilyExpression<PLUGINTYPE> AddConcreteType<PLUGGEDTYPE>() { + if (!PluginCache.GetPlugin(typeof(PLUGGEDTYPE)).CanBeAutoFilled) + { + throw new StructureMapException(231); + } + _alterations.Add(family => { string name = PluginCache.GetPlugin(typeof (PLUGGEDTYPE)).ConcreteKey; @@ -154,12 +187,24 @@ return this; } + /// <summary> + /// Registers an IBuildInterceptor for this Plugin Type that executes before + /// any object of this PluginType is created. IBuildInterceptor's can be + /// used to create a custom scope + /// </summary> + /// <param name="interceptor"></param> + /// <returns></returns> public CreatePlu... [truncated message content] |
From: <fli...@us...> - 2008-10-23 23:02:19
|
Revision: 192 http://structuremap.svn.sourceforge.net/structuremap/?rev=192&view=rev Author: flimflan Date: 2008-10-23 23:02:07 +0000 (Thu, 23 Oct 2008) Log Message: ----------- - Container.Configure() can now load load configuration from an xml file - configuration file paths are now automatically resolved to an absolute path related to the appdomain (instead of defaulting to the working directory) - GetStructureMapConfigurationPath() has been moved to ConfigurationParserBuilder Modified Paths: -------------- trunk/Source/StructureMap/Configuration/ConfigurationParserBuilder.cs trunk/Source/StructureMap/Container.cs trunk/Source/StructureMap/StructureMapConfiguration.cs trunk/Source/StructureMap.Testing/AlternativeConfigurationTester.cs trunk/Source/StructureMap.Testing/Configuration/ConfigurationParserBuilderTester.cs trunk/Source/StructureMap.Testing/TestData/Config2.xml Modified: trunk/Source/StructureMap/Configuration/ConfigurationParserBuilder.cs =================================================================== --- trunk/Source/StructureMap/Configuration/ConfigurationParserBuilder.cs 2008-10-22 14:45:15 UTC (rev 191) +++ trunk/Source/StructureMap/Configuration/ConfigurationParserBuilder.cs 2008-10-23 23:02:07 UTC (rev 192) @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.IO; using System.Xml; @@ -103,29 +104,30 @@ IList<XmlNode> appConfigNodes = StructureMapConfigurationSection.GetStructureMapConfiguration(); foreach (XmlNode appConfigNode in appConfigNodes) { - IncludeNode(appConfigNode, string.Empty); + IncludeNode(appConfigNode, String.Empty); } }).AndLogAnyErrors(); } } - private void addConfigurationFromExplicitlyAddedFiles(List<ConfigurationParser> list) + private void addConfigurationFromExplicitlyAddedFiles(ICollection<ConfigurationParser> list) { foreach (string filename in _otherFiles) { + var absolutePath = locateFileAsAbsolutePath(filename); _log.Try(() => { - ConfigurationParser parser = ConfigurationParser.FromFile(filename); - parser.Description = filename; + ConfigurationParser parser = ConfigurationParser.FromFile(absolutePath); + parser.Description = absolutePath; list.Add(parser); - }).AndReportErrorAs(160, filename); + }).AndReportErrorAs(160, absolutePath); } } - private void addConfigurationFromStructureMapConfig(List<ConfigurationParser> list) + private void addConfigurationFromStructureMapConfig(ICollection<ConfigurationParser> list) { // Pick up the configuration in the default StructureMap.config - string pathToStructureMapConfig = StructureMapConfiguration.GetStructureMapConfigurationPath(); + string pathToStructureMapConfig = GetStructureMapConfigurationPath(); if (shouldUseStructureMapConfigFileAt(pathToStructureMapConfig)) { _log.Try(() => @@ -147,10 +149,45 @@ public static ConfigurationParser[] GetParsers(XmlNode node, GraphLog log) { var builder = new ConfigurationParserBuilder(log); - builder.IncludeNode(node, string.Empty); + builder.IncludeNode(node, String.Empty); builder.IgnoreDefaultFile = true; return builder.GetParsers(); } + + /// <summary> + /// The name of the default configuration file. The value is always <c>StructurMap.config</c> + /// </summary> + public static readonly string DefaultConfigurationFilename = "StructureMap.config"; + + /// <summary> + /// Returns the absolute path to the StructureMap.config file + /// </summary> + /// <returns></returns> + public static string GetStructureMapConfigurationPath() + { + return locateFileAsAbsolutePath(DefaultConfigurationFilename); + } + + private static string locateFileAsAbsolutePath(string filename) + { + if (Path.IsPathRooted(filename)) return filename; + var basePath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase; + var configPath = Path.Combine(basePath, filename); + + if (!File.Exists(configPath)) + { + configPath = Path.Combine(basePath, "bin"); + configPath = Path.Combine(configPath, filename); + + if (!File.Exists(configPath)) + { + configPath = Path.Combine(basePath, ".."); + configPath = Path.Combine(configPath, filename); + } + } + + return configPath; + } } } \ No newline at end of file Modified: trunk/Source/StructureMap/Container.cs =================================================================== --- trunk/Source/StructureMap/Container.cs 2008-10-22 14:45:15 UTC (rev 191) +++ trunk/Source/StructureMap/Container.cs 2008-10-23 23:02:07 UTC (rev 192) @@ -350,7 +350,7 @@ var registry = new ConfigurationExpression(); configure(registry); - PluginGraph graph = registry.Build(); + PluginGraph graph = registry.BuildGraph(); graph.Log.AssertFailures(); Modified: trunk/Source/StructureMap/StructureMapConfiguration.cs =================================================================== --- trunk/Source/StructureMap/StructureMapConfiguration.cs 2008-10-22 14:45:15 UTC (rev 191) +++ trunk/Source/StructureMap/StructureMapConfiguration.cs 2008-10-23 23:02:07 UTC (rev 192) @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.IO; using System.Xml; using StructureMap.Configuration; using StructureMap.Configuration.DSL; @@ -16,7 +15,6 @@ )] public static class StructureMapConfiguration { - private const string CONFIG_FILE_NAME = "StructureMap.config"; private static GraphLog _log; private static ConfigurationParserBuilder _parserBuilder; private static List<Registry> _registries; @@ -93,24 +91,10 @@ /// Returns the path to the StructureMap.config file /// </summary> /// <returns></returns> + [Obsolete("Use ConfigurationParserBuilder.GetStructureMapConfigurationPath() instead.")] public static string GetStructureMapConfigurationPath() { - string basePath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase; - string configPath = Path.Combine(basePath, CONFIG_FILE_NAME); - - if (!File.Exists(configPath)) - { - configPath = Path.Combine(basePath, "bin"); - configPath = Path.Combine(configPath, CONFIG_FILE_NAME); - - if (!File.Exists(configPath)) - { - configPath = Path.Combine(basePath, ".."); - configPath = Path.Combine(configPath, CONFIG_FILE_NAME); - } - } - - return configPath; + return ConfigurationParserBuilder.GetStructureMapConfigurationPath(); } /// <summary> Modified: trunk/Source/StructureMap.Testing/AlternativeConfigurationTester.cs =================================================================== --- trunk/Source/StructureMap.Testing/AlternativeConfigurationTester.cs 2008-10-22 14:45:15 UTC (rev 191) +++ trunk/Source/StructureMap.Testing/AlternativeConfigurationTester.cs 2008-10-23 23:02:07 UTC (rev 192) @@ -73,5 +73,15 @@ ObjectFactory.GetInstance<IWidget>().ShouldBeOfType<ColorWidget>().Color.ShouldEqual("Red"); } + + [Test] + public void Load_configuration_file_after_the_container_has_already_been_initialized() + { + var container = new Container(x => x.AddConfigurationFromXmlFile("Config1.xml")); + + container.GetInstance<IWidget>().ShouldBeOfType<ColorWidget>().Color.ShouldEqual("Orange"); + container.Configure(x => x.AddConfigurationFromXmlFile("Config2.xml")); + container.GetInstance<IWidget>().ShouldBeOfType<ColorWidget>().Color.ShouldEqual("Green"); + } } } \ No newline at end of file Modified: trunk/Source/StructureMap.Testing/Configuration/ConfigurationParserBuilderTester.cs =================================================================== --- trunk/Source/StructureMap.Testing/Configuration/ConfigurationParserBuilderTester.cs 2008-10-22 14:45:15 UTC (rev 191) +++ trunk/Source/StructureMap.Testing/Configuration/ConfigurationParserBuilderTester.cs 2008-10-23 23:02:07 UTC (rev 192) @@ -59,7 +59,7 @@ } [Test] - public void Do_NOT_Log_exception_100_if_StructureMap_config_is_required_and_missing() + public void Do_NOT_Log_exception_100_if_StructureMap_config_is_missing_but_not_required() { assertNoErrorIsLogged(100, delegate { @@ -169,10 +169,24 @@ builder.IncludeFile("GenericsTesting.xml"); ConfigurationParser[] parsers = builder.GetParsers(); - Assert.AreEqual("GenericsTesting.xml", parsers[0].Description); + Assert.AreEqual("GenericsTesting.xml", Path.GetFileName(parsers[0].Description)); } + [Test] + public void Always_resolve_files_to_an_absolute_path_before_giving_to_configuration_parser() + { + builder.UseAndEnforceExistenceOfDefaultFile = false; + builder.IgnoreDefaultFile = true; + DataMother.WriteDocument("GenericsTesting.xml"); + + builder.IncludeFile("GenericsTesting.xml"); + + ConfigurationParser[] parsers = builder.GetParsers(); + Assert.IsTrue(Path.IsPathRooted(parsers[0].Description)); + } + + [Test] public void SimpleDefaultConfigurationParser() { Modified: trunk/Source/StructureMap.Testing/TestData/Config2.xml =================================================================== --- trunk/Source/StructureMap.Testing/TestData/Config2.xml 2008-10-22 14:45:15 UTC (rev 191) +++ trunk/Source/StructureMap.Testing/TestData/Config2.xml 2008-10-23 23:02:07 UTC (rev 192) @@ -4,7 +4,7 @@ <PluginFamily Type="StructureMap.Testing.Widget.IWidget" Assembly="StructureMap.Testing.Widget" DefaultKey="Green"> <Instance Type="Color" Key="Green"> - <Property Name="Color" Value="Green" /> + <Property Name="color" Value="Green" /> </Instance> </PluginFamily> </StructureMap> \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jer...@us...> - 2008-10-22 14:45:29
|
Revision: 191 http://structuremap.svn.sourceforge.net/structuremap/?rev=191&view=rev Author: jeremydmiller Date: 2008-10-22 14:45:15 +0000 (Wed, 22 Oct 2008) Log Message: ----------- fixing the HybridBuildPolicy and adding a method on ObjectFactory for pushing in a dictionary of arguments Modified Paths: -------------- trunk/Source/StructureMap/ObjectFactory.cs trunk/Source/StructureMap/Pipeline/ExplicitArguments.cs trunk/Source/StructureMap/Pipeline/HybridBuildPolicy.cs trunk/Source/StructureMap.Testing/ObjectFactoryTester.cs trunk/Source/StructureMap.Testing/Pipeline/BuildStrategiesTester.cs trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj Added Paths: ----------- trunk/Source/StructureMap.Testing/Pipeline/HybridBuildPolicyTester.cs Modified: trunk/Source/StructureMap/ObjectFactory.cs =================================================================== --- trunk/Source/StructureMap/ObjectFactory.cs 2008-10-21 22:15:42 UTC (rev 190) +++ trunk/Source/StructureMap/ObjectFactory.cs 2008-10-22 14:45:15 UTC (rev 191) @@ -366,5 +366,10 @@ } #endregion + + public static T GetInstance<T>(ExplicitArguments args) + { + return container.GetInstance<T>(args); + } } } \ No newline at end of file Modified: trunk/Source/StructureMap/Pipeline/ExplicitArguments.cs =================================================================== --- trunk/Source/StructureMap/Pipeline/ExplicitArguments.cs 2008-10-21 22:15:42 UTC (rev 190) +++ trunk/Source/StructureMap/Pipeline/ExplicitArguments.cs 2008-10-22 14:45:15 UTC (rev 191) @@ -5,10 +5,10 @@ { public class ExplicitArguments { - private readonly Dictionary<string, object> _args; - private readonly Dictionary<Type, object> _children = new Dictionary<Type, object>(); + private readonly IDictionary<string, object> _args; + private readonly IDictionary<Type, object> _children = new Dictionary<Type, object>(); - public ExplicitArguments(Dictionary<string, object> args) + public ExplicitArguments(IDictionary<string, object> args) { _args = args; } Modified: trunk/Source/StructureMap/Pipeline/HybridBuildPolicy.cs =================================================================== --- trunk/Source/StructureMap/Pipeline/HybridBuildPolicy.cs 2008-10-21 22:15:42 UTC (rev 190) +++ trunk/Source/StructureMap/Pipeline/HybridBuildPolicy.cs 2008-10-22 14:45:15 UTC (rev 191) @@ -4,33 +4,35 @@ { public class HybridBuildPolicy : IBuildInterceptor { - private readonly IBuildInterceptor _innerInterceptor; + private IBuildPolicy _innerPolicy; - - public HybridBuildPolicy() + private IBuildInterceptor interceptor { - _innerInterceptor = HttpContextBuildPolicy.HasContext() - ? (IBuildInterceptor) new HttpContextBuildPolicy() - : new ThreadLocalStoragePolicy(); + get + { + return HttpContextBuildPolicy.HasContext() + ? (IBuildInterceptor)new HttpContextBuildPolicy(){InnerPolicy = _innerPolicy} + : new ThreadLocalStoragePolicy(){InnerPolicy = _innerPolicy}; + } } #region IBuildInterceptor Members public IBuildPolicy InnerPolicy { - get { return _innerInterceptor.InnerPolicy; } - set { _innerInterceptor.InnerPolicy = value; } + get { return _innerPolicy; } + set { _innerPolicy = value; } } public object Build(BuildSession buildSession, Type pluginType, Instance instance) { - return _innerInterceptor.Build(buildSession, pluginType, instance); + return interceptor.Build(buildSession, pluginType, instance); } public IBuildPolicy Clone() { var policy = new HybridBuildPolicy(); - policy.InnerPolicy = InnerPolicy.Clone(); + policy.InnerPolicy = _innerPolicy.Clone(); return policy; } Modified: trunk/Source/StructureMap.Testing/ObjectFactoryTester.cs =================================================================== --- trunk/Source/StructureMap.Testing/ObjectFactoryTester.cs 2008-10-21 22:15:42 UTC (rev 190) +++ trunk/Source/StructureMap.Testing/ObjectFactoryTester.cs 2008-10-22 14:45:15 UTC (rev 191) @@ -2,6 +2,8 @@ using System.Diagnostics; using System.Linq; using NUnit.Framework; +using StructureMap.Pipeline; +using StructureMap.Testing.Graph; using StructureMap.Testing.TestData; using StructureMap.Testing.Widget; using IList=System.Collections.IList; @@ -22,7 +24,30 @@ #endregion + [Test] + public void Pass_in_arguments_as_dictionary() + { + ObjectFactory.Initialize(x => + { + x.ForRequestedType<IView>().TheDefaultIsConcreteType<View>(); + }); + + var theNode = new Node(); + var theTrade = new Trade(); + + var args = new ExplicitArguments(); + args.Set(theNode); + args.SetArg("trade", theTrade); + + var command = ObjectFactory.GetInstance<Command>(args); + + Assert.IsInstanceOfType(typeof(View), command.View); + Assert.AreSame(theNode, command.Node); + Assert.AreSame(theTrade, command.Trade); + } + + [Test] public void SmokeTestGetAllInstances() { IList list = ObjectFactory.GetAllInstances(typeof (GrandChild)); Modified: trunk/Source/StructureMap.Testing/Pipeline/BuildStrategiesTester.cs =================================================================== --- trunk/Source/StructureMap.Testing/Pipeline/BuildStrategiesTester.cs 2008-10-21 22:15:42 UTC (rev 190) +++ trunk/Source/StructureMap.Testing/Pipeline/BuildStrategiesTester.cs 2008-10-22 14:45:15 UTC (rev 191) @@ -85,7 +85,7 @@ [Test] public void CloneHybrid() { - var policy = new HybridBuildPolicy(); + var policy = new HybridBuildPolicy(){InnerPolicy = new BuildPolicy()}; var clone = (HybridBuildPolicy) policy.Clone(); Assert.AreNotSame(policy, clone); Added: trunk/Source/StructureMap.Testing/Pipeline/HybridBuildPolicyTester.cs =================================================================== --- trunk/Source/StructureMap.Testing/Pipeline/HybridBuildPolicyTester.cs (rev 0) +++ trunk/Source/StructureMap.Testing/Pipeline/HybridBuildPolicyTester.cs 2008-10-22 14:45:15 UTC (rev 191) @@ -0,0 +1,35 @@ +using System; +using System.IO; +using System.Text; +using System.Web; +using System.Web.Hosting; +using NUnit.Framework; +using StructureMap.Pipeline; +using StructureMap.Testing.DocumentationExamples; +using StructureMap.Testing.Widget3; + +namespace StructureMap.Testing.Pipeline +{ + [TestFixture] + public class HybridBuildPolicyTester + { + [Test] + public void run_without_an_httpcontext() + { + var policy = new HybridBuildPolicy(){InnerPolicy = new BuildPolicy()}; + var instance = new SmartInstance<RemoteService>(); + var object1 = policy.Build(new BuildSession(), typeof (IService), instance); + var object2 = policy.Build(new BuildSession(), typeof(IService), instance); + var object3 = policy.Build(new BuildSession(), typeof(IService), instance); + + object1.ShouldNotBeNull(); + object2.ShouldNotBeNull(); + object3.ShouldNotBeNull(); + + object1.ShouldBeTheSameAs(object2).ShouldBeTheSameAs(object3); + } + + } + + +} \ No newline at end of file Modified: trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj =================================================================== --- trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj 2008-10-21 22:15:42 UTC (rev 190) +++ trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj 2008-10-22 14:45:15 UTC (rev 191) @@ -110,6 +110,7 @@ <Name>System.Data</Name> </Reference> <Reference Include="System.Drawing" /> + <Reference Include="System.Web" /> <Reference Include="System.Web.Services" /> <Reference Include="System.Windows.Forms"> <Name>System.Windows.Forms</Name> @@ -322,6 +323,7 @@ <Compile Include="Pipeline\ConfiguredInstanceTester.cs" /> <Compile Include="Pipeline\ConstructorInstanceTester.cs" /> <Compile Include="Pipeline\DefaultInstanceTester.cs" /> + <Compile Include="Pipeline\HybridBuildPolicyTester.cs" /> <Compile Include="Pipeline\InstanceTester.cs" /> <Compile Include="Pipeline\LiteralInstanceTester.cs" /> <Compile Include="Pipeline\OptionalSetterInjectionTester.cs" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fli...@us...> - 2008-10-21 22:15:50
|
Revision: 190 http://structuremap.svn.sourceforge.net/structuremap/?rev=190&view=rev Author: flimflan Date: 2008-10-21 22:15:42 +0000 (Tue, 21 Oct 2008) Log Message: ----------- Removing dead code. Modified Paths: -------------- trunk/Source/StructureMap.Testing/Graph/ContainerTester.cs Modified: trunk/Source/StructureMap.Testing/Graph/ContainerTester.cs =================================================================== --- trunk/Source/StructureMap.Testing/Graph/ContainerTester.cs 2008-10-21 22:10:22 UTC (rev 189) +++ trunk/Source/StructureMap.Testing/Graph/ContainerTester.cs 2008-10-21 22:15:42 UTC (rev 190) @@ -26,22 +26,6 @@ registry.BuildInstancesOf<IWidget>(); registry.BuildInstancesOf<WidgetMaker>(); }); - - var container = new Container(x => - { - x.Scan(scanner => - { - scanner.Assembly("StructureMap.Testing.Widget"); - }); - - x.ForRequestedType<Rule>().TheDefault.Is.OfConcreteType<ColorRule>() - .WithCtorArg("Color").EqualTo("Blue"); - - - x.IncludeConfigurationFromConfigFile = true; - - x.AddConfigurationFromXmlFile("ExternalFile.xml"); - }); } #endregion This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jer...@us...> - 2008-10-21 22:10:30
|
Revision: 189 http://structuremap.svn.sourceforge.net/structuremap/?rev=189&view=rev Author: jeremydmiller Date: 2008-10-21 22:10:22 +0000 (Tue, 21 Oct 2008) Log Message: ----------- documentation Modified Paths: -------------- trunk/Source/HTML/HTML.csproj trunk/Source/StructureMap/Configuration/DSL/Expressions/CreatePluginFamilyExpression.cs trunk/Source/StructureMap/Configuration/DSL/Expressions/InstanceExpression.cs trunk/Source/StructureMap/Configuration/DSL/Registry.cs trunk/Source/StructureMap/InitializationExpression.cs trunk/Source/StructureMap/ObjectFactory.cs trunk/Source/StructureMap/Pipeline/SmartInstance.cs trunk/Source/StructureMap.Testing/AlternativeConfigurationTester.cs trunk/Source/StructureMap.Testing/Diagnostics/DoctorTester.cs trunk/Source/StructureMap.Testing/Examples.cs trunk/Source/StructureMap.Testing/Graph/ContainerTester.cs trunk/Source/StructureMap.Testing/Graph/DynamicInjectionTester.cs trunk/Source/StructureMap.Testing/Pipeline/SmartInstanceTester.cs Added Paths: ----------- trunk/Source/HTML/ConfiguringStructureMap.htm trunk/Source/HTML/InstanceExpression.htm trunk/Source/HTML/RegistryDSL.htm trunk/Source/StructureMap.Testing/Graph/ExplicitArgumentTester.cs Removed Paths: ------------- trunk/Source/HTML/AutoMocking.htm trunk/Source/HTML/BestPractices.htm trunk/Source/HTML/ChangingDefaultsAtRuntime.htm trunk/Source/HTML/CompositeConfiguration.htm trunk/Source/HTML/ConcreteTypes.htm trunk/Source/HTML/ConfigurationArchitecture.htm trunk/Source/HTML/ConfiguringStructureMap.htm trunk/Source/HTML/CreatingContainer.htm trunk/Source/HTML/EnvironmentTests.htm trunk/Source/HTML/FAQ.htm trunk/Source/HTML/FluentInterfaceAPI.htm trunk/Source/HTML/GentleGuide.htm trunk/Source/HTML/ImplicitInstances.htm trunk/Source/HTML/Profiles.htm trunk/Source/HTML/Scoping.htm trunk/Source/HTML/StructureMapAndMocks.htm trunk/Source/HTML/StructureMapDoctor.htm trunk/Source/HTML/TroubleShooting.htm trunk/Source/HTML/WhatWillStructureMapDoWhenI.htm Deleted: trunk/Source/HTML/AutoMocking.htm =================================================================== --- trunk/Source/HTML/AutoMocking.htm 2008-10-21 22:02:21 UTC (rev 188) +++ trunk/Source/HTML/AutoMocking.htm 2008-10-21 22:10:22 UTC (rev 189) @@ -1,9 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> -<html> - <head> - <title></title> - </head> - <body> - - </body> -</html> \ No newline at end of file Deleted: trunk/Source/HTML/BestPractices.htm =================================================================== --- trunk/Source/HTML/BestPractices.htm 2008-10-21 22:02:21 UTC (rev 188) +++ trunk/Source/HTML/BestPractices.htm 2008-10-21 22:10:22 UTC (rev 189) @@ -1,9 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> -<html> - <head> - <title></title> - </head> - <body> - - </body> -</html> \ No newline at end of file Deleted: trunk/Source/HTML/ChangingDefaultsAtRuntime.htm =================================================================== --- trunk/Source/HTML/ChangingDefaultsAtRuntime.htm 2008-10-21 22:02:21 UTC (rev 188) +++ trunk/Source/HTML/ChangingDefaultsAtRuntime.htm 2008-10-21 22:10:22 UTC (rev 189) @@ -1,9 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> -<html> - <head> - <title></title> - </head> - <body> - - </body> -</html> \ No newline at end of file Deleted: trunk/Source/HTML/CompositeConfiguration.htm =================================================================== --- trunk/Source/HTML/CompositeConfiguration.htm 2008-10-21 22:02:21 UTC (rev 188) +++ trunk/Source/HTML/CompositeConfiguration.htm 2008-10-21 22:10:22 UTC (rev 189) @@ -1,9 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> -<html> - <head> - <title></title> - </head> - <body> - - </body> -</html> \ No newline at end of file Deleted: trunk/Source/HTML/ConcreteTypes.htm =================================================================== --- trunk/Source/HTML/ConcreteTypes.htm 2008-10-21 22:02:21 UTC (rev 188) +++ trunk/Source/HTML/ConcreteTypes.htm 2008-10-21 22:10:22 UTC (rev 189) @@ -1,9 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> -<html> - <head> - <title></title> - </head> - <body> - - </body> -</html> \ No newline at end of file Deleted: trunk/Source/HTML/ConfigurationArchitecture.htm =================================================================== --- trunk/Source/HTML/ConfigurationArchitecture.htm 2008-10-21 22:02:21 UTC (rev 188) +++ trunk/Source/HTML/ConfigurationArchitecture.htm 2008-10-21 22:10:22 UTC (rev 189) @@ -1,9 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> -<html> - <head> - <title></title> - </head> - <body> - - </body> -</html> \ No newline at end of file Deleted: trunk/Source/HTML/ConfiguringStructureMap.htm =================================================================== --- trunk/Source/HTML/ConfiguringStructureMap.htm 2008-10-21 22:02:21 UTC (rev 188) +++ trunk/Source/HTML/ConfiguringStructureMap.htm 2008-10-21 22:10:22 UTC (rev 189) @@ -1,9 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> -<html> - <head> - <title></title> - </head> - <body> - - </body> -</html> \ No newline at end of file Added: trunk/Source/HTML/ConfiguringStructureMap.htm =================================================================== --- trunk/Source/HTML/ConfiguringStructureMap.htm (rev 0) +++ trunk/Source/HTML/ConfiguringStructureMap.htm 2008-10-21 22:10:22 UTC (rev 189) @@ -0,0 +1,558 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<html> + <head> + <title>Configuring StructureMap</title> + </head> + <body> + <h1>Configuring StructureMap</h1> + + + <p> + </p> + <p> + The first step in using StructureMap is configuring a Container or + ObjectFactory. The configuration options have changed more than anything + else from the initial releases to StructureMap 2.5. You have three forms + of configuration to choose from:</p> + <ol> + <li>The Registry DSL</li> + <li>Xml configuration (StructureMap.config, the App.config file, or named files)</li> + <li>StructureMap Attributes</li> + </ol> + <p> + The configuration is highly modular and you can mix and match configuration + choices within the same Container instance. The strong recommendation is + to use the Registry DSL as much as possible, and use the Xml configuration + strictly for configuration that absolutely must be external to the code + (connection strings, file paths, Url's, etc.). The attributes are + deprecated and largely unnecessary now, but still supported for backwards + compatibility.</p> + <ul> + <li>Registry - </li> + <li>StructureMap.config - </li> + <li>Xml files - </li> + <li>StructureMapConfiguration - StructureMapConfiguration is a static class that + provides an alternative for bootstrapping that was introduced in 2.0. This + class has been problematic and confusing in real world usage. At this + point, StructureMapConfiguration is deprecated and you are strongly urged to use + the ObjectFactory.Initialize() method instead.</li> + </ul> + <p> + </p> + <h4> + Initializing the Container</h4> + <p> + The recommended mechanism for initializing the Container is the Initialize() + method. The Initialize() method is a Nested Closure that acts against an + InitializationExpression object. The InitializationExpression has methods + for all all the possible configuration directives.</p> + <p> + </p> + <p> + </p> + <p> + </p> + <p> + </p> + <h4> + Using a Bootstrapper</h4> + <p> + </p> + <p> + </p> + <h4> + The StructureMap.config File</h4> + <p> + Historically, StructureMap looked for all of its configuration in a file named + "StructureMap.config" file in the ApplicationBase folder. By default, if + the StructureMap.config file is found in the ApplicationBase folder, the Xml + configuration from StructureMap.config will be applied to the internal container + of ObjectFactory. Technically, you could still do all configuration in the + StructureMap.config file. In this case, the StructureMap.config file would + be read and applied in the first call to any of the ObjectFactory methods that + request services. Likewise, StructureMap will not throw any exceptions if + the StructureMap.config file cannot be found.</p> + <p> + The default behavior can be overriden. First, if you are using the + StructureMap.config file, you might want to make the existence of this file + mandatory to prevent odd problems from missing configuration:</p> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green128\blue0;\red43\green145\blue175;\red0\green0\blue255;}??\fs20 \cf3 // This code enforces the existence of the StructureMap.config file\par ??\cf0 \cf3 // Initialize() will throw an exception if the StructureMap.config file\par ??\cf0 \cf3 // cannot be found\par ??\cf0 \cf4 ObjectFactory\cf0 .Initialize(x =>\par ?? \{\par ?? x.UseDefaultStructureMapConfigFile = \cf5 true\cf0 ;\par ?? \});} +--> +<div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> + + <span style="color: green;">// This code enforces the existence of the + StructureMap.config file</span></p> + <p style="margin: 0px;"> + + <span style="color: green;">// Initialize() will throw an exception if the + StructureMap.config file</span></p> + <p style="margin: 0px;"> + + <span style="color: green;">// cannot be found</span></p> + <p style="margin: 0px;"> + + <span style="color: #2b91af;">ObjectFactory</span>.Initialize(x =></p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + + x.UseDefaultStructureMapConfigFile = <span style="color: blue;">true</span>;</p> + <p style="margin: 0px;"> + });</p> +</div> +<!--EndFragment--> +<p> + You can also specifically ignore the StructureMap.config file at initialization + time so that the StructureMap.config file will never be used:</p> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red43\green145\blue175;\red0\green0\blue255;\red163\green21\blue21;}??\fs20 \cf3 ObjectFactory\cf0 .Initialize(x =>\par ?? \{\par ?? x.IgnoreStructureMapConfig = \cf4 true\cf0 ;\par ?? \par ?? x.ForRequestedType<\cf3 IWidget\cf0 >().TheDefault.Is\par ?? .OfConcreteType<\cf3 DoctorTester\cf0 .\cf3 NumberWidget\cf0 >()\par ?? .WithCtorArg(\cf5 "age"\cf0 ).EqualToAppSetting(\cf5 "age"\cf0 );\par ?? \});} +--> +<div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> + + <span style="color: #2b91af;">ObjectFactory</span>.Initialize(x =></p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + + x.IgnoreStructureMapConfig = <span style="color: blue;">true</span>;</p> + <p style="margin: 0px;"> + });</p> +</div> +<!--EndFragment--> +<p> + </p> +<p> + </p> +<p> + </p> +<p> + </p> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs20 \cf3 public\cf0 \cf3 class\cf0 \cf4 Bootstrapper\cf0 : \cf4 IBootstrapper\par ??\cf0 \{\par ?? \cf3 private\cf0 \cf3 static\cf0 \cf3 bool\cf0 _hasStarted;\par ??\par ??\cf3 #region\cf0 IBootstrapper Members\par ??\par ?? \cf3 public\cf0 \cf3 void\cf0 BootstrapStructureMap()\par ?? \{\par ?? \cf4 ValidationMessages\cf0 .Register();\par ??\par ?? \cf4 FilterTypeRegistry\cf0 .ResetAll();\par ??\par ?? \cf4 ObjectFactory\cf0 .Initialize(x =>\par ?? \{\par ?? x.AddRegistry(\cf3 new\cf0 \cf4 CoreRegistry\cf0 ());\par ?? x.AddRegistry(\cf3 new\cf0 \cf4 SearchRegistry\cf0 ());\par ?? x.AddRegistry(\cf3 new\cf0 \cf4 WebCoreRegistry\cf0 ());\par ?? x.AddRegistry(\cf3 new\cf0 \cf4 WebRegistry\cf0 ());\par ?? x.AddRegistry(\cf3 new\cf0 \cf4 RuleRegistry\cf0 ());\par ?? \});\par ??\par ?? \cf4 ConventionRegistry\cf0 .RegisterFor<\cf4 CultureValue\cf0 , \cf4 CultureValueObjectListConvention\cf0 >();\par ?? \}\par ??\par ??\cf3 #endregion\par ??\par ??\cf0 \cf3 public\cf0 \cf3 static\cf0 \cf3 void\cf0 Restart()\par ?? \{\par ?? \cf3 if\cf0 (_hasStarted)\par ?? \{\par ?? \cf4 ObjectFactory\cf0 .ResetDefaults();\par ?? \}\par ?? \cf3 else\par ??\cf0 \{\par ?? Bootstrap();\par ?? _hasStarted = \cf3 true\cf0 ;\par ?? \}\par ?? \}\par ??\par ?? \cf3 public\cf0 \cf3 static\cf0 \cf3 void\cf0 Bootstrap()\par ?? \{\par ?? \cf3 new\cf0 \cf4 Bootstrapper\cf0 ().BootstrapStructureMap();\par ?? \}\par ?? \}} +--> +<div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> + <span style="color: blue;">public</span> <span style="color: blue;"> + class</span> <span style="color: #2b91af;">Bootstrapper</span> : + <span style="color: #2b91af;">IBootstrapper</span></p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + <span style="color: blue;">public</span> + <span style="color: blue;">void</span> BootstrapStructureMap()</p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + + <span style="color: #2b91af;">ObjectFactory</span>.Initialize(x =></p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + + x.AddRegistry(<span style="color: blue;">new</span> + <span style="color: #2b91af;">CoreRegistry</span>());</p> + <p style="margin: 0px;"> + + x.AddRegistry(<span style="color: blue;">new</span> + <span style="color: #2b91af;">SearchRegistry</span>());</p> + <p style="margin: 0px;"> + + x.AddRegistry(<span style="color: blue;">new</span> + <span style="color: #2b91af;">WebCoreRegistry</span>());</p> + <p style="margin: 0px;"> + + x.AddRegistry(<span style="color: blue;">new</span> + <span style="color: #2b91af;">WebRegistry</span>());</p> + <p style="margin: 0px;"> + + x.AddRegistry(<span style="color: blue;">new</span> + <span style="color: #2b91af;">RuleRegistry</span>());</p> + <p style="margin: 0px;"> + });</p> + <p style="margin: 0px;"> + }</p> + <p style="margin: 0px;"> + }</p> + </div> +<!--EndFragment--> +<p style="margin: 0px"> + </p> + <p style="margin: 0px"> + </p> + <p style="margin: 0px"> + * need an example of calling this from Global.asax</p> + <p style="margin: 0px"> + * one of doing from main executable</p> + <p style="margin: 0px"> + *adding Xml file</p> + <p style="margin: 0px"> + * the StructureMap.config file</p> + <p style="margin: 0px"> + * sample Xml file</p> + <p style="margin: 0px"> + </p> + <p style="margin: 0px"> + </p> + <p style="margin: 0px"> + </p> + <h4 style="margin: 0px"> + Adding Configuration to a Container after Initialization</h4> + <p style="margin: 0px"> + </p> + <p style="margin: 0px"> + Sometimes you may want to add additional types and Instances to an existing + container. The Configure() method on both ObjectFactory and IContainer is + used for this purpose. + </p> + <p style="margin: 0px"> + </p> + <p style="margin: 0px"> + Here's a scenario. You're building a composite desktop application, and + for performance reasons you want to delay loading the screens and features for a + module of the application until the user explicitly activates that module. + When the user decides to start using that module, your code needs to immediately + add more types and Instances to the already running ObjectFactory. The + following code would search an assembly named + "MyCompany.MyApp.ExtensionAssembly" for Registry classes. The + configuration embedded in these new Registry classes would be added to the + Container internal to ObjectFactory.</p> + <p style="margin: 0px"> + </p> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green128\blue0;\red43\green145\blue175;\red163\green21\blue21;}??\fs20 \cf3 // Adding configuration from an extension Assembly\par ??\cf0 \cf3 // after ObjectFactory is already configured\par ??\cf0 \cf4 ObjectFactory\cf0 .Configure(x =>\par ?? \{\par ?? x.Scan(scan =>\par ?? \{\par ?? scan.Assembly(\cf5 "MyCompany.MyApp.ExtensionAssembly"\cf0 );\par ?? scan.LookForRegistries();\par ?? \});\par ?? \});} +--> + <div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> + + <span style="color: green;">// Adding configuration from an extension Assembly</span></p> + <p style="margin: 0px;"> + + <span style="color: green;">// after ObjectFactory is already configured</span></p> + <p style="margin: 0px;"> + + <span style="color: #2b91af;">ObjectFactory</span>.Configure(x =></p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + + x.Scan(scan =></p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + + scan.Assembly(<span style="color: #a31515;">"MyCompany.MyApp.ExtensionAssembly"</span>);</p> + <p style="margin: 0px;"> + + scan.LookForRegistries();</p> + <p style="margin: 0px;"> + + });</p> + <p style="margin: 0px;"> + });</p> + </div> +<!--EndFragment--> +<p style="margin: 0px"> + </p> + <p style="margin: 0px"> + </p> + <h4 style="margin: 0px"> + Using Container independent of ObjectFactory</h4> + <p style="margin: 0px"> + </p> + <p style="margin: 0px"> + New to 2.5 is the ability to create an instance of the underlying Container + class independent of the static ObjectFactory class (actually, you always could + do this, but it's much easier in 2.5). The IContainer interface has + roughly the same methods as ObjectFactory (the only major difference is that + ObjectFactory.GetNamedInstance<T>(name) is IContainer.GetInstance<T>(name) ) + You can build a Container with a single Registry object:</p> + <p style="margin: 0px"> + </p> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs20 \cf3 var\cf0 container = \cf3 new\cf0 \cf4 Container\cf0 (\cf3 new\cf0 \cf4 BasicActionRegistry\cf0 ());} +--> + <div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> + + <span style="color: blue;">var</span> container = <span style="color: blue;">new</span> + <span style="color: #2b91af;">Container</span>(<span style="color: blue;">new</span> + <span style="color: #2b91af;">BasicActionRegistry</span>());</p> + </div> +<!--EndFragment--> +<p style="margin: 0px"> + </p> +<p style="margin: 0px"> + Or more commonly, you can build the Container in a manner very similar to the + ObjectFactory.Initialize() method. One of the constructors for Container + takes in an Action<ConfigurationExpression><ConfigurationExpression> expression + that can be used to configure the Container in one atomic action like this code + below:</p> +<p style="margin: 0px"> + </p> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;\red163\green21\blue21;}??\fs20 \cf3 var\cf0 container = \cf3 new\cf0 \cf4 Container\cf0 (x =>\par ?? \{\par ?? x.Scan(scanner =>\par ?? \{\par ?? scanner.Assembly(\cf5 "StructureMap.Testing.Widget"\cf0 )\par ?? \});\par ??\par ?? x.ForRequestedType<\cf4 Rule\cf0 >().TheDefault.Is.OfConcreteType<\cf4 ColorRule\cf0 >()\par ?? .WithCtorArg(\cf5 "Color"\cf0 ).EqualTo(\cf5 "Blue"\cf0 );\par ??\par ??\par ?? x.IncludeConfigurationFromConfigFile = \cf3 true\cf0 ;\par ??\par ?? x.AddConfigurationFromXmlFile(\cf5 "ExternalFile.xml"\cf0 );\par ?? \});} +--> +<div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> + + <span style="color: blue;">var</span> container = <span style="color: blue;">new</span> + <span style="color: #2b91af;">Container</span>(x =></p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + + x.Scan(scanner =></p> + <p style="margin: 0px;"> + + {</p> + <p style="margin: 0px;"> + + scanner.Assembly(<span style="color: #a31515;">"StructureMap.Testing.Widget"</span>)</p> + <p style="margin: 0px;"> + + });</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + + x.ForRequestedType<<span style="color: #2b91af;">Rule</span>>().TheDefault.Is.OfConcreteType<<span + style="color: #2b91af;">ColorRule</span>>()</p> + <p style="margin: 0px;"> + + .WithCtorArg(<span style="color: #a31515;">"Color"</span>).EqualTo(<span + style="color: #a31515;">"Blue"</span>);</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + + x.IncludeConfigurationFromConfigFile = <span style="color: blue;">true</span>;</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + + x.AddConfigurationFromXmlFile(<span style="color: #a31515;">"ExternalFile.xml"</span>);</p> + <p style="margin: 0px;"> + });</p> +</div> +<!--EndFragment--> +<p style="margin: 0px"> + </p> +<p style="margin: 0px"> + The ConfigurationExpression class is a Registry, so you can use all of the + Registry DSL in the Lambda expression passed into the Container constructor. + In addition to the Registry DSL, you also have these options:</p> +<p style="margin: 0px"> + </p> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs20 \cf3 bool\cf0 IncludeConfigurationFromConfigFile \{ \cf3 set\cf0 ; \}\par ?? \cf3 void\cf0 AddRegistry<T>() \cf3 where\cf0 T : \cf4 Registry\cf0 , \cf3 new\cf0 ();\par ?? \cf3 void\cf0 AddRegistry(\cf4 Registry\cf0 registry);\par ?? \cf3 void\cf0 AddConfigurationFromXmlFile(\cf3 string\cf0 fileName);\par ?? \cf3 void\cf0 AddConfigurationFromNode(\cf4 XmlNode\cf0 node);} +--> +<div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + <span style="color: blue;">bool</span> + IncludeConfigurationFromConfigFile { <span style="color: blue;">set</span>; }</p> + <p style="margin: 0px;"> + <span style="color: blue;">void</span> + AddRegistry<T>() <span style="color: blue;">where</span> T : + <span style="color: #2b91af;">Registry</span>, <span style="color: blue;">new</span>();</p> + <p style="margin: 0px;"> + <span style="color: blue;">void</span> + AddRegistry(<span style="color: #2b91af;">Registry</span> registry);</p> + <p style="margin: 0px;"> + <span style="color: blue;">void</span> + AddConfigurationFromXmlFile(<span style="color: blue;">string</span> fileName);</p> + <p style="margin: 0px;"> + <span style="color: blue;">void</span> + AddConfigurationFromNode(<span style="color: #2b91af;">XmlNode</span> node);</p> + <p style="margin: 0px;"> + </p> +</div> +<!--EndFragment--> +<p style="margin: 0px"> + </p> +<p style="margin: 0px"> + These other options will allow you to add configuration from additional Registry + classes, the StructureMap section in the App.config file, or other Xml files.</p> +<p style="margin: 0px"> + </p> +<p style="margin: 0px"> + Lastly, you can create a Container directly with a no argument constructor, then + use the Inject() methods or later use the Configure() method.</p> +<p style="margin: 0px"> + </p> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red43\green145\blue175;\red0\green0\blue255;}??\fs20 [\cf3 Test\cf0 ]\par ?? \cf4 public\cf0 \cf4 void\cf0 Add_an_assembly_on_the_fly_and_pick_up_plugins2()\par ?? \{\par ?? \cf4 var\cf0 container = \cf4 new\cf0 \cf3 Container\cf0 ();\par ?? container.Configure(\par ?? registry =>\par ?? \{\par ?? registry.Scan(x =>\par ?? \{\par ?? x.AssemblyContainingType(\cf4 typeof\cf0 (\cf3 IService\cf0 <>));\par ?? x.AddAllTypesOf(\cf4 typeof\cf0 (\cf3 IService\cf0 <>));\par ?? \});\par ?? \}\par ?? );\par ??\par ?? \cf3 IList\cf0 <\cf3 IService\cf0 <\cf4 string\cf0 >> instances = container.GetAllInstances<\cf3 IService\cf0 <\cf4 string\cf0 >>();\par ?? instances.Count.ShouldBeGreaterThan(0);\par ?? \}} +--> +<div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> + [<span style="color: #2b91af;">Test</span>]</p> + <p style="margin: 0px;"> + <span style="color: blue;">public</span> + <span style="color: blue;">void</span> + Add_an_assembly_on_the_fly_and_pick_up_plugins2()</p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + + <span style="color: blue;">var</span> container = <span style="color: blue;">new</span> + <span style="color: #2b91af;">Container</span>();</p> + <p style="margin: 0px;"> + container.Configure(</p> + <p style="margin: 0px;"> + + registry =></p> + <p style="margin: 0px;"> + + {</p> + <p style="margin: 0px;"> + + registry.Scan(x =></p> + <p style="margin: 0px;"> + + {</p> + <p style="margin: 0px;"> + + x.AssemblyContainingType(<span style="color: blue;">typeof</span> (<span + style="color: #2b91af;">IService</span><>));</p> + <p style="margin: 0px;"> + + x.AddAllTypesOf(<span style="color: blue;">typeof</span> (<span + style="color: #2b91af;">IService</span><>));</p> + <p style="margin: 0px;"> + + });</p> + <p style="margin: 0px;"> + + }</p> + <p style="margin: 0px;"> + + );</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + + <span style="color: #2b91af;">IList</span><<span style="color: #2b91af;">IService</span><<span + style="color: blue;">string</span>>> instances = container.GetAllInstances<<span + style="color: #2b91af;">IService</span><<span style="color: blue;">string</span>>>();</p> + <p style="margin: 0px;"> + + instances.Count.ShouldBeGreaterThan(0);</p> + <p style="margin: 0px;"> + }</p> +</div> +<!--EndFragment--> +<p style="margin: 0px"> + </p> +<p style="margin: 0px"> + </p> +<p style="margin: 0px"> + </p> +<p style="margin: 0px"> + </p> +<p> + </p> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;\red0\green128\blue0;}??\fs20 \cf3 public\cf0 \cf3 class\cf0 \cf4 WebCoreRegistry\cf0 : \cf4 Registry\par ??\cf0 \{\par ?? \cf3 public\cf0 WebCoreRegistry()\par ?? \{\par ?? \cf5 // This is used as a sort of lightweight ScriptManager in\par ??\cf0 \cf5 // our website application\par ??\cf0 ForRequestedType<\cf4 ICachedSet\cf0 >().TheDefaultIsConcreteType<\cf4 CachedSet\cf0 >()\par ?? .CacheBy(\cf4 InstanceScope\cf0 .Hybrid);\par ??\par ?? ForRequestedType<\cf4 IControlBuilder\cf0 >().TheDefault.Is.OfConcreteType<\cf4 AspNetControlBuilder\cf0 >();\par ?? ForRequestedType<\cf4 IPartialRenderer\cf0 >().TheDefault.Is.OfConcreteType<\cf4 PartialRenderer\cf0 >();\par ??\par ?? Scan(x =>\par ?? \{\par ?? \cf5 // Scan "this" assembly. In other words, the assembly that \par ??\cf0 \cf5 // contains the WebCoreRegistry class\par ??\cf0 x.TheCallingAssembly();\par ??\par ?? x.IncludeNamespaceContainingType<\cf4 AuthenticationContext\cf0 >();\par ?? x.IncludeNamespaceContainingType<\cf4 ISecurityDataService\cf0 >();\par ??\par ?? x.WithDefaultConventions();\par ?? \});\par ?? \}\par ?? \}} +--> +<div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> + <span style="color: blue;">public</span> <span style="color: blue;"> + class</span> <span style="color: #2b91af;">WebCoreRegistry</span> : + <span style="color: #2b91af;">Registry</span></p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + <span style="color: blue;">public</span> + WebCoreRegistry()</p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + + <span style="color: green;">// This is used as a sort of lightweight + ScriptManager in</span></p> + <p style="margin: 0px;"> + + <span style="color: green;">// our website application</span></p> + <p style="margin: 0px;"> + ForRequestedType<<span + style="color: #2b91af;">ICachedSet</span>>().TheDefaultIsConcreteType<<span + style="color: #2b91af;">CachedSet</span>>()</p> + <p style="margin: 0px;"> + + .CacheBy(<span style="color: #2b91af;">InstanceScope</span>.Hybrid);</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + ForRequestedType<<span + style="color: #2b91af;">IControlBuilder</span>>().TheDefault.Is.OfConcreteType<<span + style="color: #2b91af;">AspNetControlBuilder</span>>();</p> + <p style="margin: 0px;"> + ForRequestedType<<span + style="color: #2b91af;">IPartialRenderer</span>>().TheDefault.Is.OfConcreteType<<span + style="color: #2b91af;">PartialRenderer</span>>();</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + Scan(x =></p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + + <span style="color: green;">// Scan "this" assembly. In other words, the + assembly that </span> + </p> + <p style="margin: 0px;"> + + <span style="color: green;">// contains the WebCoreRegistry class</span></p> + <p style="margin: 0px;"> + + x.TheCallingAssembly();</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + + x.IncludeNamespaceContainingType<<span style="color: #2b91af;">AuthenticationContext</span>>();</p> + <p style="margin: 0px;"> + + x.IncludeNamespaceContainingType<<span style="color: #2b91af;">ISecurityDataService</span>>();</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + + x.WithDefaultConventions();</p> + <p style="margin: 0px;"> + });</p> + <p style="margin: 0px;"> + }</p> + <p style="margin: 0px;"> + }</p> +</div> +<!--EndFragment--> +<p> + </p> +<h4> + </h4> +<p style="margin: 0px"> + </p> +<p style="margin: 0px"> + </p> +<p style="margin: 0px"> + </p> +<h4 style="margin: 0px"> + </h4> +<h4 style="margin: 0px"> + StructureMapConfiguration/h4> + <p style="margin: 0px"> + </p> + <p style="margin: 0px"> + </p> + + + </body> +</html> \ No newline at end of file Deleted: trunk/Source/HTML/CreatingContainer.htm =================================================================== --- trunk/Source/HTML/CreatingContainer.htm 2008-10-21 22:02:21 UTC (rev 188) +++ trunk/Source/HTML/CreatingContainer.htm 2008-10-21 22:10:22 UTC (rev 189) @@ -1,9 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> -<html> - <head> - <title></title> - </head> - <body> - - </body> -</html> \ No newline at end of file Deleted: trunk/Source/HTML/EnvironmentTests.htm =================================================================== --- trunk/Source/HTML/EnvironmentTests.htm 2008-10-21 22:02:21 UTC (rev 188) +++ trunk/Source/HTML/EnvironmentTests.htm 2008-10-21 22:10:22 UTC (rev 189) @@ -1,9 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> -<html> - <head> - <title></title> - </head> - <body> - - </body> -</html> \ No newline at end of file Deleted: trunk/Source/HTML/FAQ.htm =================================================================== --- trunk/Source/HTML/FAQ.htm 2008-10-21 22:02:21 UTC (rev 188) +++ trunk/Source/HTML/FAQ.htm 2008-10-21 22:10:22 UTC (rev 189) @@ -1,9 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> -<html> - <head> - <title></title> - </head> - <body> - - </body> -</html> \ No newline at end of file Deleted: trunk/Source/HTML/FluentInterfaceAPI.htm =================================================================== --- trunk/Source/HTML/FluentInterfaceAPI.htm 2008-10-21 22:02:21 UTC (rev 188) +++ trunk/Source/HTML/FluentInterfaceAPI.htm 2008-10-21 22:10:22 UTC (rev 189) @@ -1,13 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> -<html> - <head> - <title>Configuring StructureMap with the Programmatic API</title> - </head> - <body> - <h4>Configuring StructureMap with the Programmatic API</h4> - - <p> - </p> - - </body> -</html> \ No newline at end of file Deleted: trunk/Source/HTML/GentleGuide.htm =================================================================== --- trunk/Source/HTML/GentleGuide.htm 2008-10-21 22:02:21 UTC (rev 188) +++ trunk/Source/HTML/GentleGuide.htm 2008-10-21 22:10:22 UTC (rev 189) @@ -1,9 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> -<html> - <head> - <title></title> - </head> - <body> - - </body> -</html> \ No newline at end of file Modified: trunk/Source/HTML/HTML.csproj =================================================================== --- trunk/Source/HTML/HTML.csproj 2008-10-21 22:02:21 UTC (rev 188) +++ trunk/Source/HTML/HTML.csproj 2008-10-21 22:10:22 UTC (rev 189) @@ -58,42 +58,26 @@ --> <ItemGroup> <Content Include="AttributeNormalized.htm" /> - <Content Include="AutoMocking.htm" /> - <Content Include="BestPractices.htm" /> - <Content Include="ChangingDefaultsAtRuntime.htm" /> - <Content Include="CompositeConfiguration.htm" /> + <Content Include="ConfiguringStructureMap.htm" /> <Content Include="Example.xml" /> <Content Include="Glossary.htm" /> - <Content Include="ConcreteTypes.htm" /> - <Content Include="ConfigurationArchitecture.htm" /> - <Content Include="ConfiguringStructureMap.htm" /> - <Content Include="CreatingContainer.htm" /> <Content Include="Default.htm" /> <Content Include="Diagnostics.htm" /> - <Content Include="EnvironmentTests.htm" /> <Content Include="ExplicitArguments.htm" /> <Content Include="ExtendingStructureMap.htm" /> - <Content Include="FAQ.htm" /> - <Content Include="FluentInterfaceAPI.htm" /> + <Content Include="InstanceExpression.htm" /> + <Content Include="RegistryDSL.htm" /> <Content Include="Generics.htm" /> - <Content Include="GentleGuide.htm" /> - <Content Include="ImplicitInstances.htm" /> <Content Include="InjectingServicesAtRuntime.htm" /> <Content Include="Interception.htm" /> <Content Include="NodeNormalized.htm" /> - <Content Include="Profiles.htm" /> <Content Include="QuickStart.htm" /> <Content Include="RuntimeArchitecture.htm" /> <Content Include="Sample.xml" /> <Content Include="ScanningAssemblies.htm" /> - <Content Include="Scoping.htm" /> <Content Include="ConstructorAndSetterInjection.htm" /> - <Content Include="StructureMapAndMocks.htm" /> - <Content Include="StructureMapDoctor.htm" /> - <Content Include="TroubleShooting.htm" /> <Content Include="RetrievingServices.htm" /> <Content Include="UsingStructureMapWithinUnitTests.htm" /> - <Content Include="WhatWillStructureMapDoWhenI.htm" /> <Content Include="XmlConfiguration.htm" /> </ItemGroup> <ItemGroup> Deleted: trunk/Source/HTML/ImplicitInstances.htm =================================================================== --- trunk/Source/HTML/ImplicitInstances.htm 2008-10-21 22:02:21 UTC (rev 188) +++ trunk/Source/HTML/ImplicitInstances.htm 2008-10-21 22:10:22 UTC (rev 189) @@ -1,9 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> -<html> - <head> - <title></title> - </head> - <body> - - </body> -</html> \ No newline at end of file Added: trunk/Source/HTML/InstanceExpression.htm =================================================================== --- trunk/Source/HTML/InstanceExpression.htm (rev 0) +++ trunk/Source/HTML/InstanceExpression.htm 2008-10-21 22:10:22 UTC (rev 189) @@ -0,0 +1,551 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<html> + <head> + <title>The Instance Expression</title> + </head> + <body> + <h1>The Instance Expression</h1> + <p> + One of the most common tasks in the Registry DSL [LINK] is defining how an + Instance will be created. In an effort to standardize the Registry DSL and + make the API more predictable and consistent, we have introduced the + "InstanceExpression" as a shared + <a href="http://martinfowler.com/dslwip/ExpressionBuilder.html">Expression + Builder</a>. As of 2.5, all operations in the Registry DSL that require + the definition of an Instance expose an option to use an InstanceExpression with + these options:</p> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;\red0\green128\blue0;}??\fs20 \cf3 public\cf0 \cf3 interface\cf0 \cf4 IInstanceExpression\cf0 <T> : \cf4 IsExpression\cf0 <T>\par ?? \{\par ?? \cf5 // Attach an Instance object that is configured\par ??\cf0 \cf5 // independently of the DSL\par ??\cf0 \cf3 void\cf0 Instance(\cf4 Instance\cf0 instance);\par ?? \cf3 void\cf0 IsThis(\cf4 Instance\cf0 instance);\par ?? \par ?? \cf5 // Use a pre-built object\par ??\cf0 \cf4 LiteralInstance\cf0 IsThis(T obj);\par ?? \cf4 LiteralInstance\cf0 Object(T theObject);\par ??\par ?? \cf5 // Use a type\par ??\cf0 \cf4 SmartInstance\cf0 <PLUGGEDTYPE> OfConcreteType<PLUGGEDTYPE>() \cf3 where\cf0 PLUGGEDTYPE : T;\par ?? \cf4 ConfiguredInstance\cf0 OfConcreteType(\cf4 Type\cf0 type);\par ??\par ?? \cf5 // Build by a Lambda or an Anonymous Delegate\par ??\cf0 \cf4 ConstructorInstance\cf0 <T> ConstructedBy(\cf4 Func\cf0 <T> func);\par ?? \cf4 ConstructorInstance\cf0 <T> ConstructedBy(\cf4 Func\cf0 <\cf4 IContext\cf0 , T> func);\par ??\par ?? \cf5 // Refer to a named Instance\par ??\cf0 \cf4 ReferencedInstance\cf0 TheInstanceNamed(\cf3 string\cf0 key);\par ?? \cf4 DefaultInstance\cf0 TheDefault();\par ??\par ?? \cf5 // Use a cloned copy of the template\par ??\cf0 \cf4 PrototypeInstance\cf0 PrototypeOf(T template);\par ??\par ?? \cf5 // Cache the template as a binary serialized blob\par ??\cf0 \cf4 SerializedInstance\cf0 SerializedCopyOf(T template);\par ?? \par ?? \cf5 // Load an ASCX control\par ??\cf0 \cf4 UserControlInstance\cf0 LoadControlFrom(\cf3 string\cf0 url);\par ?? \}} +--> + <div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> + <span style="color: blue;">public</span> <span style="color: blue;"> + interface</span> <span style="color: #2b91af;">IInstanceExpression</span><T> : <span style="color: #2b91af;">IsExpression</span><T></p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + <span style="color: green;">// Attach an Instance + object that is configured</span></p> + <p style="margin: 0px;"> + <span style="color: green;">/// independently of + the DSL. This is an extensibility point</span></p> + <p style="margin: 0px;"> + <span style="color: blue;">void</span> Instance(<span + style="color: #2b91af;">Instance</span> instance);</p> + <p style="margin: 0px;"> + <span style="color: blue;">void</span> IsThis(<span + style="color: #2b91af;">Instance</span> instance);</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + <span style="color: green;">// Use a pre-built + object</span></p> + <p style="margin: 0px;"> + <span style="color: #2b91af;">LiteralInstance</span> + IsThis(T obj);</p> + <p style="margin: 0px;"> + <span style="color: #2b91af;">LiteralInstance</span> + Object(T theObject);</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + <span style="color: green;">// Use a type and + build with its constructor function</span></p> + <p style="margin: 0px;"> + <span style="color: #2b91af;">SmartInstance</span><PLUGGEDTYPE> + OfConcreteType<PLUGGEDTYPE>() <span style="color: blue;">where</span> + PLUGGEDTYPE : T;</p> + <p style="margin: 0px;"> + <span style="color: #2b91af;">ConfiguredInstance</span> + OfConcreteType(<span style="color: #2b91af;">Type</span> type);</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + <span style="color: green;">// Build by a Lambda + or an Anonymous Delegate</span></p> + <p style="margin: 0px;"> + <span style="color: #2b91af;">ConstructorInstance</span><T> + ConstructedBy(<span style="color: #2b91af;">Func</span><T> func);</p> + <p style="margin: 0px;"> + <span style="color: #2b91af;">ConstructorInstance</span><T> + ConstructedBy(<span style="color: #2b91af;">Func</span><<span + style="color: #2b91af;">IContext</span>, T> func);</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + <span style="color: green;">// Refer to a named + Instance</span></p> + <p style="margin: 0px;"> + <span style="color: #2b91af;">ReferencedInstance</span> + TheInstanceNamed(<span style="color: blue;">string</span> key);</p> + <p style="margin: 0px;"> + <span style="color: #2b91af;">DefaultInstance</span> + TheDefault();</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + <span style="color: green;">// Use a cloned copy + of the template</span></p> + <p style="margin: 0px;"> + <span style="color: #2b91af;">PrototypeInstance</span> + PrototypeOf(T template);</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + <span style="color: green;">// Cache the template + as a binary serialized blob</span></p> + <p style="margin: 0px;"> + <span style="color: #2b91af;">SerializedInstance</span> + SerializedCopyOf(T template);</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + <span style="color: green;">// Load an ASCX + control</span></p> + <p style="margin: 0px;"> + <span style="color: #2b91af;">UserControlInstance</span> + LoadControlFrom(<span style="color: blue;">string</span> url);</p> + <p style="margin: 0px;"> + }</p> + </div> +<!--EndFragment--> +<p> + Here's several examples of how the InstanceExpression is invoked. In the + code sample below, the text "**********;" represents a call to an + InstanceExpression.</p> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;\red0\green128\blue0;\red163\green21\blue21;}??\fs20 \cf3 public\cf0 \cf3 class\cf0 \cf4 InstanceExampleRegistry\cf0 : \cf4 Registry\par ??\cf0 \{\par ?? \cf3 public\cf0 InstanceExampleRegistry()\par ?? \{\par ?? \cf5 // Shortcut for just specifying "use this type -- with auto wiring"\par ??\cf0 ForRequestedType<\cf4 IService\cf0 >().TheDefaultIsConcreteType<\cf4 RemoteService\cf0 >();\par ?? \par ?? \cf5 // Set the default Instance of a PluginType\par ??\cf0 ForRequestedType<\cf4 IService\cf0 >().TheDefault.Is.OfConcreteType<\cf4 RemoteService\cf0 >();\par ?? \par ?? \cf5 // Add an additional Instance of a PluginType\par ??\cf0 InstanceOf<\cf4 IService\cf0 >().Is.OfConcreteType<\cf4 RemoteService\cf0 >();\par ??\par ?? \cf5 // Add multiple additional Instances of a PluginType\par ??\cf0 ForRequestedType<\cf4 IService\cf0 >().AddInstances(x =>\par ?? \{\par ?? x.ConstructedBy(() => \cf3 new\cf0 \cf4 ColorService\cf0 (\cf6 "Red"\cf0 ));\par ??\par ?? x.OfConcreteType<\cf4 RemoteService\cf0 >();\par ??\par ?? x.Object(\cf3 new\cf0 \cf4 ColorService\cf0 (\cf6 "Red"\cf0 ));\par ?? \});\par ??\par ?? \cf5 // Use the InstanceExpression to define the default Instance\par ??\cf0 \cf5 // of a PluginType within a Profile\par ??\cf0 CreateProfile(\cf6 "Connected"\cf0 , x =>\par ?? \{\par ?? x.Type<\cf4 IService\cf0 >().Is.OfConcreteType<\cf4 RemoteService\cf0 >();\par ?? \});\par ?? \}\par ?? \}} +--> + <div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> + <span style="color: blue;">public</span> <span style="color: blue;">class</span> + <span style="color: #2b91af;">InstanceExampleRegistry</span> : + <span style="color: #2b91af;">Registry</span></p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + <span style="color: blue;">public</span> + InstanceExampleRegistry()</p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + + <span style="color: green;">// Set the default Instance of a PluginType</span></p> + <p style="margin: 0px;"> + ForRequestedType<<span + style="color: #2b91af;">IService</span>>().TheDefault.Is.**********;</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + + <span style="color: green;">// Add an additional Instance of a PluginType</span></p> + <p style="margin: 0px;"> + InstanceOf<<span + style="color: #2b91af;">IService</span>>().Is.**********;</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + + <span style="color: green;">// Add multiple additional Instances of a PluginType</span></p> + <p style="margin: 0px;"> + ForRequestedType<<span + style="color: #2b91af;">IService</span>>().AddInstances(x =></p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + + x.**********;</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + + x.**********;</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + + x.**********;</p> + <p style="margin: 0px;"> + });</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + + <span style="color: green;">// Use the InstanceExpression to define the default + Instance</span></p> + <p style="margin: 0px;"> + + <span style="color: green;">// of a PluginType within a Profile</span></p> + <p style="margin: 0px;"> + CreateProfile(<span + style="color: #a31515;">"Connected"</span>, x =></p> + <p style="margin: 0px;"> + &nb... [truncated message content] |
From: <fli...@us...> - 2008-10-21 22:02:28
|
Revision: 188 http://structuremap.svn.sourceforge.net/structuremap/?rev=188&view=rev Author: flimflan Date: 2008-10-21 22:02:21 +0000 (Tue, 21 Oct 2008) Log Message: ----------- - Added TryGetInstance to container Modified Paths: -------------- trunk/Source/StructureMap/Container.cs trunk/Source/StructureMap/IContainer.cs trunk/Source/StructureMap.Testing/Examples.cs trunk/Source/StructureMap.Testing/Graph/AssemblyScannerTester.cs trunk/Source/StructureMap.Testing/Graph/ContainerTester.cs Modified: trunk/Source/StructureMap/Container.cs =================================================================== --- trunk/Source/StructureMap/Container.cs 2008-10-18 20:49:21 UTC (rev 187) +++ trunk/Source/StructureMap/Container.cs 2008-10-21 22:02:21 UTC (rev 188) @@ -7,6 +7,7 @@ using StructureMap.Graph; using StructureMap.Interceptors; using StructureMap.Pipeline; +using System.Linq; namespace StructureMap { @@ -215,8 +216,56 @@ return withNewSession().CreateInstance(pluginType, instanceKey); } + /// <summary> + /// Creates or finds the named instance of the pluginType. Returns null if the named instance is not known to the container. + /// </summary> + /// <param name="pluginType"></param> + /// <param name="instanceKey"></param> + /// <param name="instance"></param> + /// <returns></returns> + public object TryGetInstance(Type pluginType, string instanceKey) + { + return _pipelineGraph.ForType(pluginType).FindInstance(instanceKey) == null + ? null + : GetInstance(pluginType, instanceKey); + } /// <summary> + /// Creates or finds the default instance of the pluginType. Returns null if the pluginType is not known to the container. + /// </summary> + /// <param name="pluginType"></param> + /// <param name="instance"></param> + /// <returns></returns> + public object TryGetInstance(Type pluginType) + { + return !_pipelineGraph.PluginTypes.Any(p => p.PluginType == pluginType) + ? null + : GetInstance(pluginType); + } + + /// <summary> + /// Creates or finds the default instance of type T. Returns the default value of T if it is not known to the container. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="instance"></param> + /// <returns></returns> + public T TryGetInstance<T>() + { + return (T)(TryGetInstance(typeof (T)) ?? default(T)); + } + + /// <summary> + /// Creates or finds the named instance of type T. Returns the default value of T if the named instance is not known to the container. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="instance"></param> + /// <returns></returns> + public T TryGetInstance<T>(string instanceKey) + { + return (T)(TryGetInstance(typeof(T), instanceKey) ?? default(T)); + } + + /// <summary> /// Creates or finds the default instance of the pluginType /// </summary> /// <param name="pluginType"></param> Modified: trunk/Source/StructureMap/IContainer.cs =================================================================== --- trunk/Source/StructureMap/IContainer.cs 2008-10-18 20:49:21 UTC (rev 187) +++ trunk/Source/StructureMap/IContainer.cs 2008-10-21 22:02:21 UTC (rev 188) @@ -76,6 +76,40 @@ /// <returns></returns> IList GetAllInstances(Type pluginType); + /// <summary> + /// Creates or finds the named instance of the pluginType. Returns null if the named instance is not known to the container. + /// </summary> + /// <param name="pluginType"></param> + /// <param name="instanceKey"></param> + /// <param name="instance"></param> + /// <returns></returns> + object TryGetInstance(Type pluginType, string instanceKey); + + /// <summary> + /// Creates or finds the default instance of the pluginType. Returns null if the pluginType is not known to the container. + /// </summary> + /// <param name="pluginType"></param> + /// <param name="instance"></param> + /// <returns></returns> + object TryGetInstance(Type pluginType); + + /// <summary> + /// Creates or finds the default instance of type T. Returns the default value of T if it is not known to the container. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="instance"></param> + /// <returns></returns> + T TryGetInstance<T>(); + + /// <summary> + /// Creates or finds the named instance of type T. Returns the default value of T if the named instance is not known to the container. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="instance"></param> + /// <returns></returns> + T TryGetInstance<T>(string instanceKey); + + [Obsolete("Please use GetInstance<T>() instead.")] T FillDependencies<T>(); @@ -188,6 +222,5 @@ /// </summary> /// <typeparam name="T"></typeparam> void EjectAllInstancesOf<T>(); - } } \ No newline at end of file Modified: trunk/Source/StructureMap.Testing/Examples.cs =================================================================== --- trunk/Source/StructureMap.Testing/Examples.cs 2008-10-18 20:49:21 UTC (rev 187) +++ trunk/Source/StructureMap.Testing/Examples.cs 2008-10-21 22:02:21 UTC (rev 188) @@ -7,7 +7,7 @@ using StructureMap.Configuration.DSL; using StructureMap.Testing.Widget3; -namespace StructureMap.Testing +namespace StructureMap.Testing.DocumentationExamples { public interface IDataProvider { Modified: trunk/Source/StructureMap.Testing/Graph/AssemblyScannerTester.cs =================================================================== --- trunk/Source/StructureMap.Testing/Graph/AssemblyScannerTester.cs 2008-10-18 20:49:21 UTC (rev 187) +++ trunk/Source/StructureMap.Testing/Graph/AssemblyScannerTester.cs 2008-10-21 22:02:21 UTC (rev 188) @@ -63,7 +63,9 @@ var scanner = new AssemblyScanner(); action(scanner); theGraph = new PluginGraph(); + scanner.ExcludeNamespaceContainingType<DocumentationExamples.ScanningRegistry>(); scanner.ScanForAll(theGraph); + theGraph.Log.AssertFailures(); } @@ -129,7 +131,7 @@ } [Test] - public void Search_for_registries_by_default() + public void Search_for_registries_when_explicitly_told() { Scan(x => { Modified: trunk/Source/StructureMap.Testing/Graph/ContainerTester.cs =================================================================== --- trunk/Source/StructureMap.Testing/Graph/ContainerTester.cs 2008-10-18 20:49:21 UTC (rev 187) +++ trunk/Source/StructureMap.Testing/Graph/ContainerTester.cs 2008-10-21 22:02:21 UTC (rev 188) @@ -195,6 +195,82 @@ Assert.AreEqual("Orange", maker.Color); } + [Test] + public void TryGetInstanceViaName_ReturnsNull_WhenNotFound() + { + addColorInstance("Red"); + addColorInstance("Orange"); + addColorInstance("Blue"); + + var rule = _container.TryGetInstance(typeof(Rule), "Yellow"); + rule.ShouldBeNull(); + } + + [Test] + public void TryGetInstanceViaName_ReturnsTheOutInstance_WhenFound() + { + addColorInstance("Red"); + addColorInstance("Orange"); + addColorInstance("Blue"); + + var rule = _container.TryGetInstance(typeof(Rule), "Orange"); + rule.ShouldBeOfType(typeof(ColorRule)); + } + + [Test] + public void TryGetInstance_ReturnsNull_WhenTypeNotFound() + { + var instance = _container.TryGetInstance(typeof(IProvider)); + instance.ShouldBeNull(); + } + + [Test] + public void TryGetInstance_ReturnsInstance_WhenTypeFound() + { + _container.Configure(c => c.ForRequestedType<IProvider>().TheDefaultIsConcreteType<Provider>()); + var instance = _container.TryGetInstance(typeof(IProvider)); + instance.ShouldBeOfType(typeof(Provider)); + } + + [Test] + public void TryGetInstanceViaGeneric_ReturnsNull_WhenTypeNotFound() + { + var instance = _container.TryGetInstance<IProvider>(); + instance.ShouldBeNull(); + } + + [Test] + public void TryGetInstanceViaGeneric_ReturnsInstance_WhenTypeFound() + { + _container.Configure(c => c.ForRequestedType<IProvider>().TheDefaultIsConcreteType<Provider>()); + var instance = _container.TryGetInstance<IProvider>(); + instance.ShouldBeOfType(typeof(Provider)); + } + + [Test] + public void TryGetInstanceViaNameAndGeneric_ReturnsNull_WhenTypeNotFound() + { + addColorInstance("Red"); + addColorInstance("Orange"); + addColorInstance("Blue"); + + var instance = _container.TryGetInstance<Rule>("Yellow"); + instance.ShouldBeNull(); + } + + [Test] + public void TryGetInstanceViaNameAndGeneric_ReturnsInstance_WhenTypeFound() + { + addColorInstance("Red"); + addColorInstance("Orange"); + addColorInstance("Blue"); + + var instance = _container.TryGetInstance<Rule>("Orange"); + instance.ShouldBeOfType(typeof(ColorRule)); + } + + + [Test, ExpectedException(typeof (StructureMapException))] public void GetMissingType() { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jer...@us...> - 2008-10-18 20:49:28
|
Revision: 187 http://structuremap.svn.sourceforge.net/structuremap/?rev=187&view=rev Author: jeremydmiller Date: 2008-10-18 20:49:21 +0000 (Sat, 18 Oct 2008) Log Message: ----------- documentation Modified Paths: -------------- trunk/Source/CommonAssemblyInfo.cs trunk/Source/HTML/Glossary.htm trunk/Source/HTML/ScanningAssemblies.htm trunk/Source/StructureMap/Graph/AssemblyScanner.cs trunk/Source/StructureMap/Pipeline/Instance.cs trunk/Source/StructureMap.Testing/Examples.cs Modified: trunk/Source/CommonAssemblyInfo.cs =================================================================== --- trunk/Source/CommonAssemblyInfo.cs 2008-10-18 13:26:11 UTC (rev 186) +++ trunk/Source/CommonAssemblyInfo.cs 2008-10-18 20:49:21 UTC (rev 187) @@ -5,7 +5,7 @@ //------------------------------------------------------------------------------ // <auto-generated> // This code was generated by a tool. -// Runtime Version:2.0.50727.1433 +// Runtime Version:2.0.50727.1434 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. Modified: trunk/Source/HTML/Glossary.htm =================================================================== --- trunk/Source/HTML/Glossary.htm 2008-10-18 13:26:11 UTC (rev 186) +++ trunk/Source/HTML/Glossary.htm 2008-10-18 20:49:21 UTC (rev 187) @@ -184,8 +184,122 @@ <!--EndFragment--> <p> </p> <h4>Instance</h4> - <p>In StructureMap terms, an "Instance" is a named way to build or locate an object - instance for a requested PluginType. There is an actual class in + <p>In StructureMap terms, an "Instance" is a named way to build or locate a + named object + instance for a requested PluginType. An "Instance" does not automatically + equate to a concrete type. For example, let's say that we're building a + system to automate a warehouse. Our system might consume an interface + called IShippingService that acts as a Gateway[LINK] to various ways of shipping + boxes out of our warehouse.</p> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs20 \cf3 public\cf0 \cf3 interface\cf0 \cf4 IShippingService\par ??\cf0 \{\par ?? \cf3 void\cf0 ShipIt();\par ?? \}} +--> + <div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> + <span style="color: blue;">public</span> <span style="color: blue;"> + interface</span> <span style="color: #2b91af;">IShippingService</span></p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + <span style="color: blue;">void</span> ShipIt();</p> + <p style="margin: 0px;"> + }</p> + </div> +<!--EndFragment--> +<p>Our warehouse system might have to interact with three types of shipping: + domestic, international, and intra-company or internal shipments. The + internal shipping service runs in process with the warehouse application, but + domestic and international shipping is done by invoking external web services. + The registration of the IShippingService Instances might look like this:</p> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;\red163\green21\blue21;}??\fs20 \cf3 public\cf0 \cf3 class\cf0 \cf4 ShippingRegistry\cf0 : \cf4 Registry\par ??\cf0 \{\par ?? \cf3 public\cf0 ShippingRegistry()\par ?? \{\par ?? ForRequestedType<\cf4 IShippingService\cf0 >().AddInstances(x =>\par ?? \{\par ?? x.OfConcreteType<\cf4 ShippingWebService\cf0 >()\par ?? .WithCtorArg(\cf5 "url"\cf0 ).EqualTo(\cf5 "a url"\cf0 )\par ?? .WithName(\cf5 "Domestic"\cf0 );\par ??\par ?? x.OfConcreteType<\cf4 ShippingWebService\cf0 >()\par ?? .WithCtorArg(\cf5 "url"\cf0 ).EqualTo(\cf5 "a different url"\cf0 )\par ?? .WithName(\cf5 "International"\cf0 );\par ??\par ?? x.OfConcreteType<\cf4 InternalShippingService\cf0 >().WithName(\cf5 "Internal"\cf0 );\par ?? \});\par ?? \}\par ?? \}} +--> +<div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> + <span style="color: blue;">public</span> <span style="color: blue;"> + class</span> <span style="color: #2b91af;">ShippingRegistry</span> : + <span style="color: #2b91af;">Registry</span></p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + <span style="color: blue;">public</span> + ShippingRegistry()</p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + ForRequestedType<<span + style="color: #2b91af;">IShippingService</span>>().AddInstances(x =></p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + + x.OfConcreteType<<span style="color: #2b91af;">ShippingWebService</span>>()</p> + <p style="margin: 0px;"> + + .WithCtorArg(<span style="color: #a31515;">"url"</span>).EqualTo(<span + style="color: #a31515;">"a url"</span>)</p> + <p style="margin: 0px;"> + + .WithName(<span style="color: #a31515;">"Domestic"</span>);</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + + x.OfConcreteType<<span style="color: #2b91af;">ShippingWebService</span>>()</p> + <p style="margin: 0px;"> + + .WithCtorArg(<span style="color: #a31515;">"url"</span>).EqualTo(<span + style="color: #a31515;">"a different url"</span>)</p> + <p style="margin: 0px;"> + + .WithName(<span style="color: #a31515;">"International"</span>);</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + + x.OfConcreteType<<span style="color: #2b91af;">InternalShippingService</span>>().WithName(<span + style="color: #a31515;">"Internal"</span>);</p> + <p style="margin: 0px;"> + });</p> + <p style="margin: 0px;"> + }</p> + <p style="margin: 0px;"> + }</p> +</div> +<!--EndFragment--> +<p>In the registration code above, there are three "Instance's." You can + access the various IShippingService Instance's by name:</p> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green128\blue0;\red0\green0\blue255;\red43\green145\blue175;\red163\green21\blue21;}??\fs20 \cf3 // Accessing the IShippingService Instance's by name\par ??\cf0 \cf4 var\cf0 internationalService = \cf5 ObjectFactory\cf0 .GetNamedInstance<\cf5 IShippingService\cf0 >(\cf6 "International"\cf0 );\par ?? \cf4 var\cf0 domesticService = \cf5 ObjectFactory\cf0 .GetNamedInstance<\cf5 IShippingService\cf0 >(\cf6 "Domestic"\cf0 );\par ?? \cf4 var\cf0 internalService = \cf5 ObjectFactory\cf0 .GetNamedInstance<\cf5 IShippingService\cf0 >(\cf6 "Internal"\cf0 );\par ??} +--> +<div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> + + <span style="color: green;">// Accessing the IShippingService Instance's by name</span></p> + <p style="margin: 0px;"> + + <span style="color: blue;">var</span> internationalService = + <span style="color: #2b91af;">ObjectFactory</span>.GetNamedInstance<<span + style="color: #2b91af;">IShippingService</span>>(<span + style="color: #a31515;">"International"</span>);</p> + <p style="margin: 0px;"> + + <span style="color: blue;">var</span> domesticService = + <span style="color: #2b91af;">ObjectFactory</span>.GetNamedInstance<<span + style="color: #2b91af;">IShippingService</span>>(<span + style="color: #a31515;">"Domestic"</span>);</p> + <p style="margin: 0px;"> + + <span style="color: blue;">var</span> internalService = + <span style="color: #2b91af;">ObjectFactory</span>.GetNamedInstance<<span + style="color: #2b91af;">IShippingService</span>>(<span + style="color: #a31515;">"Internal"</span>);</p> +</div> +<!--EndFragment--> +<p>Asking for the "International" or the "Domestic" instance of IShippingService + will both return an object of type ShippingWebService, but the two objects will + be differently configured with unique Url's.</p> +<p>There is an actual class in StructureMap 2.5 that represents an "Instance." An abreviated version of the abstract Instance class is shown below:</p> <!-- @@ -296,16 +410,212 @@ method to create a new object or get an existing object. Note the abstract build(Type, IBuildSession) method. This is a Template Method that can be overriden to write your own customized Instance type.</p> -<p>When you call ObjectFactory.Get</p> - <h4>Scoping</h4> - <p>a;lskdfje</p> - <h4>PluginFamily</h4> - <p>a;lskdfj</p> - <h4>Profile</h4> - <p>a;lskdfj</p> +<p>When you call ObjectFactory.GetNamedInstance<T>("the instance that I want") or + ObjectFactory.GetInstance<T>(), the internal Container object is locating the + correct Instance object and calling its Build() method.</p> + <h4>Scoping (or Lifecycle)</h4> + <p>When you register a PluginType in the system you can "scope" the Instance's of + that PluginType like this:</p> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green128\blue0;\red43\green145\blue175;}??\fs20 \cf3 // This is used as a sort of lightweight ScriptManager in\par ??\cf0 \cf3 // our website application\par ??\cf0 ForRequestedType<\cf4 ICachedSet\cf0 >().TheDefaultIsConcreteType<\cf4 CachedSet\cf0 >()\par ?? .CacheBy(\cf4 InstanceScope\cf0 .Hybrid);\par ??} +--> + <div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> + + <span style="color: green;">// This is used as a sort of lightweight + ScriptManager in</span></p> + <p style="margin: 0px;"> + + <span style="color: green;">// our website application</span></p> + <p style="margin: 0px;"> + ForRequestedType<<span + style="color: #2b91af;">ICachedSet</span>>().TheDefaultIsConcreteType<<span + style="color: #2b91af;">CachedSet</span>>()</p> + <p style="margin: 0px;"> + + .CacheBy(<span style="color: #2b91af;">InstanceScope</span>.HttpContext);</p> + </div> +<!--EndFragment--> +<p>Note the CacheBy() method hanging off the end of the expression. This is + directing the StructureMap container to use the same object instance for + ICachedSet for all requests in the same HttpContext. In this case, if a + request is made for any Instance of ICachedSet, StructureMap will first check + the HttpContext.Items collection to see if that exact Instance has already been + created within the same HttpContext. </p> + <ol> + <li>PerRequest - The default option unless otherwise overridden. A new object + will be created for each time you request an Instance from the container. + Some other IoC containers call this "Transient." Please note that this is + the default behavior in StructureMap. Many other IoC container tools will + use "Singleton" instead. </li> + <li>Singleton - A single object will be shared across + all requests for a specific Instance. StructureMap will only create the + singleton object upon demand</li> + <li>ThreadLocal - A single object will be created for + each requesting thread. Caches the instances with + ThreadLocalStorage.</li> + <li>HttpContext - A single object will be created for + each HttpContext. Caches the instances in the + HttpContext.Items collection.</li> + <li>Hybrid - Uses HttpContext storage if it exists, + otherwise uses ThreadLocal storage.</li> + </ol> + <p> + It is possible to create your own type of scoping. See "Extending + StructureMap" [LINK -- doesn't exist yet] for more information. Also note + that StructureMap provides no functionality for cleaning up resources of the + objects held by the container. To date, I have not found a need for this + behavior or functionality. I generally assume that a combination of basic + garbage collection and proper class design is sufficient.</p> + <h4> </h4> + <h4>Profile</h4> + <p>From the very beginning, StructureMap has supported the ability to define a named + set of default instances called a "Profile." The Profile feature was + originally meant to be a quick way of switching the connection mode of a smart + client application from connected to disconnected modes. In practice, it's + more commonly used as a way to migrate configuration between environments or for + creating alternative deployment configurations. My team uses the Profile + feature in our system as a quick way to collapse our entire distributed + application into a single AppDomain for easier testing and debugging. Our + "InMemory" profile is defined like this:</p> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green128\blue0;\red0\green0\blue255;\red43\green145\blue175;}??\fs20 \cf3 // Using this Profile configures our application to \par ??\cf0 \cf3 // run completely inside a single AppDomain\par ??\cf0 \cf3 // In production the application will consist\par ??\cf0 \cf3 // of the website and 2-3 external windows\par ??\cf0 \cf3 // services\par ??\cf0 \cf4 var\cf0 repository = \cf4 new\cf0 \cf5 InMemoryRepository\cf0 ();\par ?? CreateProfile(IN_MEMORY_PROFILE, x =>\par ?? \{\par ?? x.For<\cf5 IRepository\cf0 >().Use(repository);\par ?? x.For<\cf5 IEventPublishingService\cf0 >().Use(\cf4 new\cf0 \cf5 InMemoryEventPublishingService\cf0 (repository));\par ?? x.For<\cf5 IUserMessagePublisher\cf0 >().UseConcreteType<\cf5 InMemoryUserMessageQueue\cf0 >();\par ?? x.For<\cf5 IUnitOfWork\cf0 >().UseConcreteType<\cf5 InMemoryUnitOfWork\cf0 >();\par ?? \});} +--> + <div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> + + <span style="color: green;">// Using this Profile configures our application to + </span> + </p> + <p style="margin: 0px;"> + + <span style="color: green;">// run completely inside a single AppDomain</span></p> + <p style="margin: 0px;"> + + <span style="color: green;">// In production the application will consist</span></p> + <p style="margin: 0px;"> + + <span style="color: green;">// of the website and 2-3 external windows</span></p> + <p style="margin: 0px;"> + + <span style="color: green;">// services</span></p> + <p style="margin: 0px;"> + + <span style="color: blue;">var</span> repository = <span style="color: blue;"> + new</span> <span style="color: #2b91af;">InMemoryRepository</span>();</p> + <p style="margin: 0px;"> + + CreateProfile(IN_MEMORY_PROFILE, x =></p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + + x.For<<span style="color: #2b91af;">IRepository</span>>().Use(repository);</p> + <p style="margin: 0px;"> + + x.For<<span style="color: #2b91af;">IEventPublishingService</span>>().Use(<span + style="color: blue;">new</span> <span style="color: #2b91af;"> + InMemoryEventPublishingService</span>(repository));</p> + <p style="margin: 0px;"> + + x.For<<span style="color: #2b91af;">IUserMessagePublisher</span>>().UseConcreteType<<span + style="color: #2b91af;">InMemoryUserMessageQueue</span>>();</p> + <p style="margin: 0px;"> + + x.For<<span style="color: #2b91af;">IUnitOfWork</span>>().UseConcreteType<<span + style="color: #2b91af;">InMemoryUnitOfWork</span>>();</p> + <p style="margin: 0px;"> + });</p> + </div> +<!--EndFragment--> +<p>In the code, we can switch the application to the in memory mode by calling the + SetDefaultsToProfile() method on the Container (or ObjectFactory.Profile = + CoreRegistry.IN_MEMORY_PROFILE):</p> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green128\blue0;\red43\green145\blue175;\red0\green0\blue255;}??\fs20 \cf3 // This is actual code from a test harness class we use\par ??\cf0 \cf3 // for integration testing\par ??\cf0 \cf4 IContainer\cf0 container = createContainer(\cf5 new\cf0 \cf4 RuleSet\cf0 []\{ruleSet\});\par ?? container.SetDefaultsToProfile(\cf4 CoreRegistry\cf0 .IN_MEMORY_PROFILE);\par ??} +--> +<div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> + + <span style="color: green;">// This is actual code from a test harness class we + use</span></p> + <p style="margin: 0px;"> + + <span style="color: green;">// for integration testing</span></p> + <p style="margin: 0px;"> + + <span style="color: #2b91af;">IContainer</span> container = createContainer(<span + style="color: blue;">new</span> <span style="color: #2b91af;">RuleSet</span>[]{ruleSet});</p> + <p style="margin: 0px;"> + + container.SetDefaultsToProfile(<span style="color: #2b91af;">CoreRegistry</span>.IN_MEMORY_PROFILE);</p> +</div> +<!--EndFragment--> +<p> </p> <h4>Interceptor</h4> - <p>a;lskdfj</p> - <h4>PostProcessor</h4> - <p>a;lskdfj</p> + <p>A new feature for StructureMap 2.5 is the ability to "intercept" an object + getting created in StructureMap before the new object is handed back to the + requesting code. The intention behind this feature is to support runtime + Aspect Oriented Programming techniques or any type of object initialization + beyond the constructor function. </p> + <p> + To explain the sequence of events, here's an ellided version of the Build() + method of the Instance abstract class:</p> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;\red0\green128\blue0;}??\fs20 \cf3 public\cf0 \cf3 virtual\cf0 \cf3 object\cf0 Build(\cf4 Type\cf0 pluginType, \cf4 BuildSession\cf0 session)\par ?? \{\par ?? markBuildStackStart(session, pluginType);\par ??\par ?? \cf5 // "Build" the desired object\par ??\cf0 \cf3 object\cf0 rawValue = createRawObject(pluginType, session);\par ?? \par ?? \cf5 // Allow the Interceptor a chance to enhance, configure, \par ??\cf0 \cf5 // wrap with a decorator, or even replace the rawValue\par ??\cf0 \cf3 object\cf0 finalValue = applyInterception(rawValue, pluginType);\par ??\par ?? markBuildStackFinish(session);\par ??\par ?? \cf3 return\cf0 finalValue;\par ?? \}} +--> + <div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> + <span style="color: blue;">public</span> + <span style="color: blue;">virtual</span> <span style="color: blue;">object</span> + Build(<span style="color: #2b91af;">Type</span> pluginType, + <span style="color: #2b91af;">BuildSession</span> session)</p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + + markBuildStackStart(session, pluginType);</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + + <span style="color: green;">// "Build" the desired object</span></p> + <p style="margin: 0px;"> + + <span style="color: blue;">object</span> rawValue = createRawObject(pluginType, + session);</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + + <span style="color: green;">// Allow the Interceptor a chance to enhance, + configure, </span> + </p> + <p style="margin: 0px;"> + + <span style="color: green;">// wrap with a decorator, or even replace the + rawValue</span></p> + <p style="margin: 0px;"> + + <span style="color: blue;">object</span> finalValue = + applyInterception(rawValue, pluginType);</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + + markBuildStackFinish(session);</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + + <span style="color: blue;">return</span> finalValue;</p> + <p style="margin: 0px;"> + }</p> + </div> +<!--EndFragment--> +<p> + The Instance class first builds the raw object, then applies any registered + interception on the raw object to get the final value. +</p> </body> </html> \ No newline at end of file Modified: trunk/Source/HTML/ScanningAssemblies.htm =================================================================== --- trunk/Source/HTML/ScanningAssemblies.htm 2008-10-18 13:26:11 UTC (rev 186) +++ trunk/Source/HTML/ScanningAssemblies.htm 2008-10-18 20:49:21 UTC (rev 187) @@ -92,8 +92,16 @@ <p> The actual work is performed by an IAssemblyScanner object. The Scan() method uses the <a href="http://martinfowler.com/dslwip/NestedClosure.html"> - Nested Closure</a> pattern as a way of configuring the IAssemblyScanner and then - executing the scanner at the correct time in the configuration process. + Nested Closure</a> pattern as a way of configuring and registering the IAssemblyScanner + in a single atomic action. Each Scan() expression is a completely + self-contained, atomic action. This is a significant change from the + earlier functionality in versions 2.0 and 2.4.9. This breaking change was + made to reduce confusion by making the actual functionality more closely match + the DSL expression. </p> +<p> + The scanner itself will not be executed until near the end of the configuration process. + Be aware of this issue if you are trying to debug custom ITypeScanner classes.</p> +<p> The IAssemblyScanner interface exposes these directives to control the assembly scanning:</p> <!-- @@ -188,55 +196,624 @@ </div> <!--EndFragment--> <p> - </p> + Roughly put, these are the features and options of each individual Scan() + expression:</p> +<ol> + <li>Analyzing all the exported types in the specified Assembly's</li> + <li>By default, looking for all types decorated with either the [PluginFamily] or + [Pluggable] attributes. This feature can be disabled by calling the + IAssemblyScanner.IgnoreStructureMapAttributes() method. See NEED A LINK + HERE for more information</li> + <li><b>If explicitly specified</b> with the use of the LookForRegistries() method, + the scanning will apply the configuration contained within any concrete Registry + class found in the assemblies being scanned.</li> + <li>Optionally, the scanning can automatically add any concrete types found that can + be "plugged" into a given PluginType</li> + <li>The scanning of types within an Assembly can be further filtered by specifying + rules to either include or exclude types based on Predicate<Type> rules[LINK].</li> + <li>Lastly, custom scanning conventions and policies can be added and used from the + Scan() expression. </li> +</ol> <h4> Rules for Auto Registering a Type</h4> +<p> + If you are interested in using the Scan() expression for auto registration, the + first thing to know is how StructureMap determines whether or not a given + concrete type should be registered. </p> +<p> + </p> +<ul> + <li>The PluginType is assignable from the concrete type</li> + <li>The concrete type has a public constructor</li> + <li>Cannot have a primitive constructor argument</li> + <li>Auto scanning only works if there is only one concrete type registered for a + PluginType</li> + <li>The scanning can be overridden explicitly</li> +</ul> <h4> - Designating Assemblies <h4> + Designating Assemblies +<p> + The first thing you need to do to utilize the type scanning is to designate + which assemblies to scan. The type scanning will throw an exception if you + attempt to call the Scan() expression without designating at least one assembly. + Use one of the following methods on IAssemblyScanner to designate assemblies:\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;\red0\green128\blue0;}??\fs20 \cf3 public\cf0 \cf3 interface\cf0 \cf4 IAssemblyScanner\par ??\cf0 \{\par ?? \cf5 // Determining which assemblies to scan\par ??\cf0 \cf3 void\cf0 Assembly(\cf4 Assembly\cf0 assembly);\par ?? \cf3 void\cf0 Assembly(\cf3 string\cf0 assemblyName);\par ?? \cf3 void\cf0 TheCallingAssembly();\par ?? \cf3 void\cf0 AssemblyContainingType<T>();\par ?? \cf3 void\cf0 AssemblyContainingType(\cf4 Type\cf0 type);\par ?? \cf3 void\cf0 AssembliesFromPath(\cf3 string\cf0 path);\par ?? \cf3 void\cf0 AssembliesFromPath(\cf3 string\cf0 path, \cf4 Predicate\cf0 <\cf4 Assembly\cf0 > assemblyFilter);\par ?? \par ?? \cf5 // Adding conventions\par ??\cf0 \cf3 void\cf0 With(\cf4 ITypeScanner\cf0 scanner);\par ?? \cf3 void\cf0 WithDefaultConventions();\par ?? \cf3 void\cf0 With<T>() \cf3 where\cf0 T : \cf4 ITypeScanner\cf0 , \cf3 new\cf0 ();\par ?? \par ?? \cf5 // Other options\par ??\cf0 \cf3 void\cf0 LookForRegistries();\par ?? \cf3 void\cf0 AddAllTypesOf<PLUGINTYPE>();\par ?? \cf3 void\cf0 AddAllTypesOf(\cf4 Type\cf0 pluginType);\par ?? \cf3 void\cf0 IgnoreStructureMapAttributes();\par ?? \par ?? \cf5 // Filtering the types that will be scanned\par ??\cf0 \cf3 void\cf0 Exclude(\cf4 Predicate\cf0 <\cf4 Type\cf0 > exclude);\par ?? \cf3 void\cf0 ExcludeNamespace(\cf3 string\cf0 nameSpace);\par ?? \cf3 void\cf0 ExcludeNamespaceContainingType<T>();\par ?? \cf3 void\cf0 Include(\cf4 Predicate\cf0 <\cf4 Type\cf0 > predicate);\par ?? \cf3 void\cf0 IncludeNamespace(\cf3 string\cf0 nameSpace);\par ?? \cf3 void\cf0 IncludeNamespaceContainingType<T>();\par ?? \cf3 void\cf0 ExcludeType<T>();\par ?? \}} +--> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;\red0\green128\blue0;}??\fs20 \cf3 public\cf0 \cf3 interface\cf0 \cf4 IAssemblyScanner\par ??\cf0 \{\par ??\cf3 #region\cf0 Designating Assemblies\par ??\par ?? \cf3 void\cf0 Assembly(\cf4 Assembly\cf0 assembly);\par ?? \cf3 void\cf0 Assembly(\cf3 string\cf0 assemblyName);\par ?? \cf3 void\cf0 TheCallingAssembly();\par ?? \cf3 void\cf0 AssemblyContainingType<T>();\par ?? \cf3 void\cf0 AssemblyContainingType(\cf4 Type\cf0 type);\par ?? \cf3 void\cf0 AssembliesFromPath(\cf3 string\cf0 path);\par ?? \cf3 void\cf0 AssembliesFromPath(\cf3 string\cf0 path, \cf4 Predicate\cf0 <\cf4 Assembly\cf0 > assemblyFilter);\par ??\par ??\cf3 #endregion\par ??\par ??\cf0 \cf5 // ... Other methods\par ??\par ??\cf3 #region\cf0 Adding TypeScanners\par ??\par ?? \cf3 void\cf0 With(\cf4 ITypeScanner\cf0 scanner);\par ?? \cf3 void\cf0 WithDefaultConventions();\par ?? \cf3 void\cf0 With<T>() \cf3 where\cf0 T : \cf4 ITypeScanner\cf0 , \cf3 new\cf0 ();\par ??\par ??\cf3 #endregion\par ??\par ?? #region\cf0 Other options\par ??\par ?? \cf3 void\cf0 LookForRegistries();\par ?? \cf3 void\cf0 AddAllTypesOf<PLUGINTYPE>();\par ?? \cf3 void\cf0 AddAllTypesOf(\cf4 Type\cf0 pluginType);\par ?? \cf3 void\cf0 IgnoreStructureMapAttributes();\par ??\par ??\cf3 #endregion\par ??\par ?? #region\cf0 Filtering types\par ??\par ?? \cf3 void\cf0 Exclude(\cf4 Predicate\cf0 <\cf4 Type\cf0 > exclude);\par ?? \cf3 void\cf0 ExcludeNamespace(\cf3 string\cf0 nameSpace);\par ?? \cf3 void\cf0 ExcludeNamespaceContainingType<T>();\par ?? \cf3 void\cf0 Include(\cf4 Predicate\cf0 <\cf4 Type\cf0 > predicate);\par ?? \cf3 void\cf0 IncludeNamespace(\cf3 string\cf0 nameSpace);\par ?? \cf3 void\cf0 IncludeNamespaceContainingType<T>();\par ?? \cf3 void\cf0 ExcludeType<T>();\par ??\par ??\cf3 #endregion\par ??\par ??\cf0 \}} +--> +<div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> + <span style="color: blue;">public</span> <span style="color: blue;"> + interface</span> <span style="color: #2b91af;">IAssemblyScanner</span></p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + <span style="color: blue;">void</span> + Assembly(<span style="color: #2b91af;">Assembly</span> assembly);</p> + <p style="margin: 0px;"> + <span style="color: blue;">void</span> + Assembly(<span style="color: blue;">string</span> assemblyName);</p> + <p style="margin: 0px;"> + <span style="color: blue;">void</span> + TheCallingAssembly();</p> + <p style="margin: 0px;"> + <span style="color: blue;">void</span> + AssemblyContainingType<T>();</p> + <p style="margin: 0px;"> + <span style="color: blue;">void</span> + AssemblyContainingType(<span style="color: #2b91af;">Type</span> type);</p> + <p style="margin: 0px;"> + <span style="color: blue;">void</span> + AssembliesFromPath(<span style="color: blue;">string</span> path);</p> + <p style="margin: 0px;"> + <span style="color: blue;">void</span> + AssembliesFromPath(<span style="color: blue;">string</span> path, + <span style="color: #2b91af;">Predicate</span><<span style="color: #2b91af;">Assembly</span>> + assemblyFilter);</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + <span style="color: green;">// ... Other methods</span></p> + <p style="margin: 0px;"> + }</p> + </div> +<!--EndFragment--> +<p> + Adding an assembly directly:</p> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;\red0\green128\blue0;\red163\green21\blue21;}??\fs20 \cf3 public\cf0 \cf3 class\cf0 \cf4 ScanningRegistry\cf0 : \cf4 Registry\par ??\cf0 \{\par ?? \cf3 public\cf0 ScanningRegistry()\par ?? \{\par ?? Scan(x =>\par ?? \{\par ?? \cf5 // Add assembly by name.\par ??\cf0 x.Assembly(\cf6 "StructureMap.Testing.Widget"\cf0 );\par ??\par ?? \cf5 // Add an assembly directly\par ??\cf0 x.Assembly(\cf4 Assembly\cf0 .GetExecutingAssembly());\par ??\par ?? \cf5 // Add the assembly that contains a certain type\par ??\cf0 x.AssemblyContainingType<\cf4 IService\cf0 >();\par ?? \cf5 // or\par ??\cf0 x.AssemblyContainingType(\cf3 typeof\cf0 (\cf4 IService\cf0 ));\par ?? \});\par ?? \}\par ?? \}} +--> +<div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> + <span style="color: blue;">public</span> <span style="color: blue;"> + class</span> <span style="color: #2b91af;">ScanningRegistry</span> : + <span style="color: #2b91af;">Registry</span></p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + <span style="color: blue;">public</span> + ScanningRegistry()</p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + Scan(x =></p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + + <span style="color: green;">// Add assembly by name.</span></p> + <p style="margin: 0px;"> + + x.Assembly(<span style="color: #a31515;">"StructureMap.Testing.Widget"</span>);</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + + <span style="color: green;">// Add an assembly directly</span></p> + <p style="margin: 0px;"> + + x.Assembly(<span style="color: #2b91af;">Assembly</span>.GetExecutingAssembly());</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + + <span style="color: green;">// Add the assembly that contains a certain type</span></p> + <p style="margin: 0px;"> + + x.AssemblyContainingType<<span style="color: #2b91af;">IService</span>>();</p> + <p style="margin: 0px;"> + + <span style="color: green;">// or</span></p> + <p style="margin: 0px;"> + + x.AssemblyContainingType(<span style="color: blue;">typeof</span>(<span + style="color: #2b91af;">IService</span>));</p> + <p style="margin: 0px;"> + });</p> + <p style="margin: 0px;"> + }</p> + <p style="margin: 0px;"> + }</p> +</div> +<!--EndFragment--> +<p> + The most common usage is probably just specifying "this" assembly with + IAssemblyScanner.TheCallingAssembly():</p> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;\red0\green128\blue0;}??\fs20 \cf3 public\cf0 \cf3 class\cf0 \cf4 WebCoreRegistry\cf0 : \cf4 Registry\par ??\cf0 \{\par ?? \cf3 protected\cf0 \cf3 override\cf0 \cf3 void\cf0 configure()\par ?? \{\par ?? ForRequestedType<\cf4 ICachedSet\cf0 >().TheDefaultIsConcreteType<\cf4 CachedSet\cf0 >().CacheBy(\cf4 InstanceScope\cf0 .Hybrid);\par ?? ForRequestedType<\cf4 IControlBuilder\cf0 >().TheDefault.Is.OfConcreteType<\cf4 AspNetControlBuilder\cf0 >();\par ?? ForRequestedType<\cf4 IPartialRenderer\cf0 >().TheDefault.Is.OfConcreteType<\cf4 PartialRenderer\cf0 >();\par ??\par ?? Scan(x =>\par ?? \{\par ?? \cf5 // Scan "this" assembly. In other words, the assembly that \par ??\cf0 \cf5 // contains the WebCoreRegistry class\par ??\cf0 x.TheCallingAssembly();\par ??\par ?? x.IncludeNamespaceContainingType<\cf4 AuthenticationContext\cf0 >();\par ?? x.IncludeNamespaceContainingType<\cf4 ISecurityDataService\cf0 >();\par ??\par ?? x.WithDefaultConventions();\par ?? \});\par ?? \}\par ?? \}} +--> +<div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> + <span style="color: blue;">public</span> <span style="color: blue;"> + class</span> <span style="color: #2b91af;">WebCoreRegistry</span> : + <span style="color: #2b91af;">Registry</span></p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + <span style="color: blue;">protected</span> + <span style="color: blue;">override</span> <span style="color: blue;">void</span> + configure()</p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + ForRequestedType<<span + style="color: #2b91af;">ICachedSet</span>>().TheDefaultIsConcreteType<<span + style="color: #2b91af;">CachedSet</span>>().CacheBy(<span + style="color: #2b91af;">InstanceScope</span>.Hybrid);</p> + <p style="margin: 0px;"> + ForRequestedType<<span + style="color: #2b91af;">IControlBuilder</span>>().TheDefault.Is.OfConcreteType<<span + style="color: #2b91af;">AspNetControlBuilder</span>>();</p> + <p style="margin: 0px;"> + ForRequestedType<<span + style="color: #2b91af;">IPartialRenderer</span>>().TheDefault.Is.OfConcreteType<<span + style="color: #2b91af;">PartialRenderer</span>>();</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + Scan(x =></p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + + <span style="color: green;">// Scan "this" assembly. In other words, the + assembly that </span> + </p> + <p style="margin: 0px;"> + + <span style="color: green;">// contains the WebCoreRegistry class</span></p> + <p style="margin: 0px;"> + + x.TheCallingAssembly();</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + + x.IncludeNamespaceContainingType<<span style="color: #2b91af;">AuthenticationContext</span>>();</p> + <p style="margin: 0px;"> + + x.IncludeNamespaceContainingType<<span style="color: #2b91af;">ISecurityDataService</span>>();</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + + x.WithDefaultConventions();</p> + <p style="margin: 0px;"> + });</p> + <p style="margin: 0px;"> + }</p> + <p style="margin: 0px;"> + }</p> +</div> +<p> + StructureMap 2.5 has a brand new capability to auto register types in all + assemblies in a given folder path. My current project is using this + feature for our extensibility mechanism. For customer-specific + deployments, we need to add business rules and even all new screens and features + to our application that can be discovered at runtime -- without changing our + core code. Our design calls for all extensions to be created in separate + assemblies. On application startup, our system will look for all + assemblies in a well known folder and use StructureMap to scan these assemblies + for the extensions that will be specified in Registry classes. Our + bootstrapping looks like:</p> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green128\blue0;\red163\green21\blue21;}??\fs20 Scan(x =>\par ?? \{\par ?? \cf3 // I'm telling StructureMap to sweep a folder called "Extensions" directly\par ??\cf0 \cf3 // underneath the application root folder for any assemblies\par ??\cf0 x.AssembliesFromPath(\cf4 "Extensions"\cf0 );\par ??\par ?? \cf3 // I also direct StructureMap to add any Registries that it finds in these\par ??\cf0 \cf3 // assemblies. I'm assuming that all the StructureMap directives are\par ??\cf0 \cf3 // contained in Registry classes -- and this is the recommended approach\par ??\cf0 x.LookForRegistries();\par ?? \});} +--> +<div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> + Scan(x =></p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + + <span style="color: green;">// I'm telling StructureMap to sweep a folder called + "Extensions" directly</span></p> + <p style="margin: 0px;"> + + <span style="color: green;">// underneath the application root folder for any + assemblies found in that folder</span></p> + <p style="margin: 0px;"> + + x.AssembliesFromPath(<span style="color: #a31515;">"Extensions"</span>);</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + + <span style="color: green;">// I also direct StructureMap to add any Registries + that it finds in these</span></p> + <p style="margin: 0px;"> + + <span style="color: green;">// assemblies. I'm assuming that all the + StructureMap directives are</span></p> + <p style="margin: 0px;"> + + <span style="color: green;">// contained in Registry classes -- and this is the + recommended approach</span></p> + <p style="margin: 0px;"> + + x.LookForRegistries();</p> + <p style="margin: 0px;"> + });</p> +</div> +<!--EndFragment--> +<p> + Note in the code above that I made an explicit call to "LookForRegistries." + Scanning for Registry's is no longer active by default. This is a breaking + change from the 2.4.9 preview release. +</p> +<p> + You can also filter the assemblies based on a Predicate like this:</p> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green128\blue0;\red163\green21\blue21;}??\fs20 Scan(x =>\par ?? \{\par ?? \cf3 // This time I'm going to specify a filter on the assembly such that \par ??\cf0 \cf3 // only assemblies that have "Extension" in their name will be scanned\par ??\cf0 x.AssembliesFromPath(\cf4 "Extensions"\cf0 , assembly => assembly.GetName().Name.Contains(\cf4 "Extension"\cf0 ));\par ??\par ?? x.LookForRegistries();\par ?? \});} +--> +<div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> + Scan(x =></p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + + <span style="color: green;">// This time I'm going to specify a filter on the + assembly such that </span> + </p> + <p style="margin: 0px;"> + + <span style="color: green;">// only assemblies that have "Extension" in their + name will be scanned</span></p> + <p style="margin: 0px;"> + + x.AssembliesFromPath(<span style="color: #a31515;">"Extensions"</span>, assembly + => assembly.GetName().Name.Contains(<span style="color: #a31515;">"Extension"</span>));</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + + x.LookForRegistries();</p> + <p style="margin: 0px;"> + });</p> +</div> +<!--EndFragment--> +<p> + </p> +<p> + </p> +<h4> Add All Concrete Types for a PluginType</h4> +<p> + Sometimes you may simply want to automatically add all the concrete classes that + implement or inherit from a given PluginType. In my current project we are + using StructureMap to bootstrap and configure NHibernate. We're also using + Fluent NHibernate for our mapping configuration. The mapping configuration + is specified in classes that implement an interface named IDomainMap. To + configure NHibernate, we need to sweep our core assembly to find all concrete + implementations of IDomainMap and execute the mappings on each type. We + have a Registry called "CoreRegistry" that configures NHibernate (among other + things). We specify the auto registration of all the IDomainMap types like + this:</p> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green128\blue0;\red43\green145\blue175;}??\fs20 Scan(x =>\par ?? \{\par ?? \cf3 // Scan the types in the assembly that contains this Registry class\par ??\cf0 x.TheCallingAssembly();\par ??\par ?? x.ExcludeNamespaceContainingType<\cf4 IEvent\cf0 >();\par ?? x.ExcludeNamespaceContainingType<\cf4 SearchModel\cf0 >();\par ?? x.ExcludeNamespaceContainingType<\cf4 AuthenticationService\cf0 >();\par ?? x.ExcludeNamespaceContainingType<\cf4 DovetailController\cf0 >();\par ??\par ?? \cf3 // Finds and adds all concrete implementations of the IDomainMap\par ??\cf0 \cf3 // interface in the targetted assemblies\par ??\cf0 x.AddAllTypesOf<\cf4 IDomainMap\cf0 >();\par ?? x.WithDefaultConventions();\par ?? x.With<\cf4 DomainEntityAliaser\cf0 >();\par ?? \});} +--> +<div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> + Scan(x =></p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + + <span style="color: green;">// Scan the types in the assembly that contains this + Registry class</span></p> + <p style="margin: 0px;"> + + x.TheCallingAssembly();</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + + <span style="color: green;">// Finds and adds all concrete implementations of + the IDomainMap</span></p> + <p style="margin: 0px;"> + + <span style="color: green;">// interface in the targetted assemblies</span></p> + <p style="margin: 0px;"> + + x.AddAllTypesOf<<span style="color: #2b91af;">IDomainMap</span>>();</p> + <p style="margin: 0px;"> + });</p> +</div> +<!--EndFragment--> +<p> + After running the Scan() statement above, we can retrieve an instance of all the + IDomainMap types by calling:</p> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green128\blue0;\red43\green145\blue175;}??\fs20 \par ?? \cf3 // Retrieve all registered IDomainMap objects\par ??\cf0 \cf4 IList\cf0 <\cf4 IDomainMap\cf0 > allMaps = \cf4 ObjectFactory\cf0 .GetAllInstances<\cf4 IDomainMap\cf0 >();\par ??} +--> +<div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + + <span style="color: green;">// Retrieve all registered IDomainMap objects</span></p> + <p style="margin: 0px;"> + + <span style="color: #2b91af;">IList</span><<span style="color: #2b91af;">IDomainMap</span>> + allMaps = <span style="color: #2b91af;">ObjectFactory</span>.GetAllInstances<<span + style="color: #2b91af;">IDomainMap</span>>();</p> + <p style="margin: 0px;"> + </p> +</div> +<!--EndFragment--> +<p> + More appropriately in our code, we have a "Query" subsystem that also uses the + IDomainMap objects for its metadata. We have a class called + EntityQueryRepository that "knows" how each Domain Model class is queried. + When the EntityQueryRepository object is created, it takes in an array of + IDomainMap objects.</p> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green128\blue0;\red0\green0\blue255;\red43\green145\blue175;}??\fs20 \cf3 // Unless explicitly configured otherwise, when StructureMap\par ??\cf0 \cf3 // sees a constructor or setter argument that is an array,\par ??\cf0 \cf3 // it will fill this argument with all of the instances\par ??\cf0 \cf3 // of the argument type -- in this case, all the registered\par ??\cf0 \cf3 // IDomainMap objects\par ??\cf0 \cf4 public\cf0 EntityQueryRegistry(\cf5 IDomainMap\cf0 [] maps)\par ?? \{\par ?? maps.Each(m => m.RegisterQueryModel(\cf4 this\cf0 ));\par ?? \}} +--> +<div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> + <span style="color: green;">// Unless + explicitly configured otherwise, when StructureMap</span></p> + <p style="margin: 0px;"> + <span style="color: green;">// sees a + constructor or setter argument that is an array,</span></p> + <p style="margin: 0px;"> + <span style="color: green;">// it will fill + this argument with all of the instances</span></p> + <p style="margin: 0px;"> + <span style="color: green;">// of the + argument type -- in this case, all the registered</span></p> + <p style="margin: 0px;"> + <span style="color: green;">// IDomainMap + objects</span></p> + <p style="margin: 0px;"> + <span style="color: blue;">public</span> + EntityQueryRegistry(<span style="color: #2b91af;">IDomainMap</span>[] maps)</p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + maps.Each(m => + m.RegisterQueryModel(<span style="color: blue;">this</span>));</p> + <p style="margin... [truncated message content] |
From: <jer...@us...> - 2008-10-18 13:26:17
|
Revision: 186 http://structuremap.svn.sourceforge.net/structuremap/?rev=186&view=rev Author: jeremydmiller Date: 2008-10-18 13:26:11 +0000 (Sat, 18 Oct 2008) Log Message: ----------- Added a last minute defensive programming check on TheDefaultInstanceIsConcreteType Modified Paths: -------------- trunk/Source/StructureMap/Configuration/DSL/Expressions/CreatePluginFamilyExpression.cs trunk/Source/StructureMap/StructureMapException.resx trunk/Source/StructureMap.Testing/Configuration/DSL/CreatePluginFamilyTester.cs Modified: trunk/Source/StructureMap/Configuration/DSL/Expressions/CreatePluginFamilyExpression.cs =================================================================== --- trunk/Source/StructureMap/Configuration/DSL/Expressions/CreatePluginFamilyExpression.cs 2008-10-18 13:13:17 UTC (rev 185) +++ trunk/Source/StructureMap/Configuration/DSL/Expressions/CreatePluginFamilyExpression.cs 2008-10-18 13:26:11 UTC (rev 186) @@ -71,6 +71,11 @@ ExpressionValidator.ValidatePluggabilityOf(concreteType).IntoPluginType(_pluginType); + if (!PluginCache.GetPlugin(concreteType).CanBeAutoFilled) + { + throw new StructureMapException(231); + } + return alterAndContinue(family => { ConfiguredInstance instance = Modified: trunk/Source/StructureMap/StructureMapException.resx =================================================================== --- trunk/Source/StructureMap/StructureMapException.resx 2008-10-18 13:13:17 UTC (rev 185) +++ trunk/Source/StructureMap/StructureMapException.resx 2008-10-18 13:26:11 UTC (rev 186) @@ -262,4 +262,7 @@ <data name="125" xml:space="preserve"> <value>Cannot plug an abstract class or an interface</value> </data> + <data name="231" xml:space="preserve"> + <value>Cannot use the "TheDefaultIsConcreteType" method with an object that has primitive constructor arguments. Use the "TheDefault.Is.OfConcreteType<T>()" method instead and specify the primitive constructor arguments</value> + </data> </root> \ No newline at end of file Modified: trunk/Source/StructureMap.Testing/Configuration/DSL/CreatePluginFamilyTester.cs =================================================================== --- trunk/Source/StructureMap.Testing/Configuration/DSL/CreatePluginFamilyTester.cs 2008-10-18 13:13:17 UTC (rev 185) +++ trunk/Source/StructureMap.Testing/Configuration/DSL/CreatePluginFamilyTester.cs 2008-10-18 13:26:11 UTC (rev 186) @@ -35,7 +35,30 @@ { } + public class ClassWithStringInConstructor + { + public ClassWithStringInConstructor(string name){} + } + [Test] + public void cannot_use_a_class_with_a_primitive_constructor_in_the_TheDefaultIsConcreteType_shortcut() + { + try + { + var container = new Container(x => + { + x.ForRequestedType<ClassWithStringInConstructor>().TheDefaultIsConcreteType + <ClassWithStringInConstructor>(); + }); + Assert.Fail("Should have thrown exception 231"); + } + catch (StructureMapException e) + { + e.ErrorCode.ShouldEqual(231); + } + } + + [Test] public void Add_an_instance_by_lambda() { var manager = This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jer...@us...> - 2008-10-18 13:13:21
|
Revision: 185 http://structuremap.svn.sourceforge.net/structuremap/?rev=185&view=rev Author: jeremydmiller Date: 2008-10-18 13:13:17 +0000 (Sat, 18 Oct 2008) Log Message: ----------- auto mocker tweaks Modified Paths: -------------- trunk/Source/StructureMap.AutoMocking/AutoMocker.cs Modified: trunk/Source/StructureMap.AutoMocking/AutoMocker.cs =================================================================== --- trunk/Source/StructureMap.AutoMocking/AutoMocker.cs 2008-10-18 03:05:42 UTC (rev 184) +++ trunk/Source/StructureMap.AutoMocking/AutoMocker.cs 2008-10-18 13:13:17 UTC (rev 185) @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Reflection; using StructureMap.Graph; +using System.Linq; namespace StructureMap.AutoMocking { @@ -87,8 +88,13 @@ /// </summary> /// <typeparam name="T"></typeparam> /// <returns></returns> - public T Get<T>() + public T Get<T>() where T : class { + if (!_container.Model.HasDefaultImplementationFor(typeof(T))) + { + _container.Inject<T>(_serviceLocator.Service<T>()); + } + return _container.GetInstance<T>(); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jer...@us...> - 2008-10-18 03:05:58
|
Revision: 184 http://structuremap.svn.sourceforge.net/structuremap/?rev=184&view=rev Author: jeremydmiller Date: 2008-10-18 03:05:42 +0000 (Sat, 18 Oct 2008) Log Message: ----------- html updates, ndoc type documentation, merged rhino mocker Modified Paths: -------------- trunk/Source/HTML/ConstructorAndSetterInjection.htm trunk/Source/HTML/HTML.csproj trunk/Source/HTML/ScanningAssemblies.htm trunk/Source/StructureMap/BuildSession.cs trunk/Source/StructureMap/Configuration/DSL/Expressions/InstanceExpression.cs trunk/Source/StructureMap/Configuration/DSL/Registry.cs trunk/Source/StructureMap/Container.cs trunk/Source/StructureMap/ExplicitArgsExpression.cs trunk/Source/StructureMap/Graph/AssemblyScanner.cs trunk/Source/StructureMap/Graph/PluginGraph.cs trunk/Source/StructureMap/IContainer.cs trunk/Source/StructureMap/Model.cs trunk/Source/StructureMap/ObjectFactory.cs trunk/Source/StructureMap/Pipeline/BuildStack.cs trunk/Source/StructureMap/Pipeline/Instance.cs trunk/Source/StructureMap/PipelineGraph.cs trunk/Source/StructureMap/StructureMapConfiguration.cs trunk/Source/StructureMap.AutoMocking/AutoMockedContainer.cs trunk/Source/StructureMap.AutoMocking/RhinoAutoMocker.cs trunk/Source/StructureMap.AutoMocking/ServiceLocator.cs trunk/Source/StructureMap.AutoMocking/StructureMap.AutoMocking.csproj trunk/Source/StructureMap.Testing/AutoMocking/RhinoAutoMockerTester.cs trunk/Source/StructureMap.Testing/Configuration/DSL/AddInstanceTester.cs trunk/Source/StructureMap.Testing/Configuration/DSL/DeepInstanceTester.cs trunk/Source/StructureMap.Testing/Configuration/DSL/InjectArrayTester.cs trunk/Source/StructureMap.Testing/Diagnostics/ValidationBuildSessionTester.cs trunk/Source/StructureMap.Testing/Graph/ContainerTester.cs trunk/Source/StructureMap.Testing/Graph/DynamicInjectionTester.cs trunk/Source/StructureMap.Testing/Graph/FullStackFacadeTester.cs trunk/Source/StructureMap.Testing/Graph/IntegratedTester.cs trunk/Source/StructureMap.Testing/Graph/TestExplicitArguments.cs trunk/Source/StructureMap.Testing/Pipeline/OptionalSetterInjectionTester.cs trunk/Source/StructureMap.sln Added Paths: ----------- trunk/Source/HTML/Example.xml trunk/Source/StructureMap.AutoMocking/AutoMocker.cs Modified: trunk/Source/HTML/ConstructorAndSetterInjection.htm =================================================================== --- trunk/Source/HTML/ConstructorAndSetterInjection.htm 2008-10-17 19:00:37 UTC (rev 183) +++ trunk/Source/HTML/ConstructorAndSetterInjection.htm 2008-10-18 03:05:42 UTC (rev 184) @@ -11,7 +11,7 @@ <ol> <li>Constructor Injection -- "Pushing" dependencies into a concrete class through constructor arguments.</li> - <li>Setter Injection -- "Pushing" depencencies into a concrete class through public + <li>Setter Injection -- "Pushing" dependencies into a concrete class through public properties. The "Setter" nomenclature is taken from Java where properties are getSomething() and setSomething(value).</li> </ol> @@ -24,7 +24,7 @@ Martin Fowler's discussion on Constructor versus Setter Injection</a> for more information. My feeling has always been that Constructor Injection is preferrable from a design perspective. When you exclusively use - Constructor Injection, the code is somewhat self-documenting because the + Constructor Injection, the code is somewhat more self-documenting because the constructor arguments will clearly delineate the dependencies of a concrete class. It's also important to think about the constructor method of a class being a contract. If you satisfy all of the arguments of the @@ -33,10 +33,14 @@ which setters need to be created externally to use the class. Of course, not using any form of Dependency Injection can be the worst answer because then you have no idea what it really takes to bootstrap the service. </p> + <p>Despite my personal distaste for Setter Injection, I gave into user demand and + greatly increased StructureMap's support for Setter Injection -- and promptly + found that support to be more useful than I thought it would be.</p> <h2>Using Constructor Injection</h2> <p>Now, the first question you might ask is how does StructureMap know which constructor function to use in a class that has multiple constructors? The - answer is that StructureMap will automatically select the "greediest" public + answer is that StructureMap will automatically select the "greediest" + <b>public</b> constructor of a class to use for injection. In this case, the "greediest" constructor is the constructor with the most arguments. In the case of a tie, StructureMap will use the first constructor that it encountered. For @@ -111,96 +115,357 @@ [InternalsVisibleTo] attribute to give StructureMap access to your own internal members. StructureMap 2.5 is now strongly signed (thanks to <a href="http://stevenharman.net/">Steve Harman</a>) partially for this - scenario. There is an architectural limitation </p> + scenario. </p> <h2>Using Setter Injection</h2> <p>Setter injection is a pattern of "injecting" dependencies via public properties. - Setter Injection with StructureMap is admittedly a second class citizen, but + Setter Injection with StructureMap is somewhat a second class citizen, but this is partially by design. My strong recommendation is to use constructor injection for all code that you control, and save setter injection - strictly for classes from external libraries where you do not have any control. </p> + strictly for classes from external libraries where you do not have any control. + As a summary, these are the Setter Injection features that are described in + detail below:</p> + <ul> + <li>By default, all public "Setters" are optional, meaning that these setters will + only be set if they are explicitly configured for a specific Instance</li> + <li>StructureMap can be directed to "auto wire" a property for a given Instance</li> + <li>Setters can be made mandatory by decorating the property with the + [SetterProperty] attribute</li> + <li>Any type that StructureMap can use in constructor arguments can be used for + setter properties</li> + <li>StructureMap can be directed to automatically inject the default value for any + property of a given type. This was added primarily for "optional" + dependencies like logging.</li> + <li>The StructureMap diagnostic tools will check for missing Setter values</li> + </ul> - <p>Ok, now that you've read that I don't believe that setter injection is a good - idea, but you're bound and determined to use it anyway, let's talk about how to - do it with StructureMap. First off, StructureMap needs to be explicitly - told to build a concrete class with each setter. These setter properties - are then considered to be mandatory anytime an Instance of that concrete type is - requested. StructureMap does not support optional setter properties (but - it could easily be done with the new post processing support). That - restriction may be relaxed in later versions.</p> - <p>Once StructureMap does know to use a setter in constructing a class, configuring - the actual property values is done no differently than constructor arguments.</p> - <p>Let's say you have a class called Repository with these properties:</p> - + <h4>Configuring Primitive Setter Properties</h4> + <p>Ok, now that you've read that I don't believe that setter injection is a good + idea, but you're bound and determined to use it anyway, let's talk about how to + do it with StructureMap. Let's say we have this class with a string + property called "Name":</p> <!-- -{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs20 \cf3 public\cf0 \cf3 interface\cf0 \cf4 IDataProvider\cf0 \{\}\par ??\par ?? \cf3 public\cf0 \cf3 class\cf0 \cf4 Repository\par ??\cf0 \{\par ?? \cf3 private\cf0 \cf4 IDataProvider\cf0 _provider;\par ??\par ?? \cf3 public\cf0 \cf4 IDataProvider\cf0 Provider\par ?? \{\par ?? \cf3 set\par ??\cf0 \{\par ?? _provider = \cf3 value\cf0 ;\par ?? \}\par ?? \}\par ?? \}} +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs20 \cf3 public\cf0 \cf3 class\cf0 \cf4 OptionalSetterTarget\par ??\cf0 \{\par ?? \cf3 public\cf0 \cf3 string\cf0 Name \{ \cf3 get\cf0 ; \cf3 set\cf0 ; \}\par ?? \cf3 public\cf0 \cf3 string\cf0 Name2 \{ \cf3 get\cf0 ; \cf3 set\cf0 ; \}\par ?? \}} --> - <div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"> + <div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> <p style="margin: 0px;"> - </p> + <span style="color: blue;">public</span> <span style="color: blue;">class</span> + <span style="color: #2b91af;">OptionalSetterTarget</span></p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + <span style="color: blue;">public</span> + <span style="color: blue;">string</span> Name { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>;; }</p> + <p style="margin: 0px;"> + }</p> + </div> +<!--EndFragment--> +<p>I can specify the value of the "Name" property in the configuration API like + this:</p> <!-- -{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs20 \cf3 public\cf0 \cf3 interface\cf0 \cf4 IDataProvider\cf0 \{\}\par ??\par ?? \cf3 public\cf0 \cf3 class\cf0 \cf4 Repository\par ??\cf0 \{\par ?? \cf3 private\cf0 \cf4 IDataProvider\cf0 _provider;\par ??\par ?? \cf3 public\cf0 \cf4 IDataProvider\cf0 Provider\par ?? \{\par ?? \cf3 set\par ??\cf0 \{\par ?? _provider = \cf3 value\cf0 ;\par ?? \}\par ?? \}\par ?? \}} +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red43\green145\blue175;\red0\green0\blue255;\red0\green128\blue0;\red163\green21\blue21;}??\fs20 [\cf3 Test\cf0 ]\par ?? \cf4 public\cf0 \cf4 void\cf0 optional_setter_injection_with_string()\par ?? \{\par ?? \cf4 var\cf0 container = \cf4 new\cf0 \cf3 Container\cf0 (r =>\par ?? \{\par ?? \cf5 // The "Name" property is not configured for this instance\par ??\cf0 r.InstanceOf<\cf3 OptionalSetterTarget\cf0 >().Is.OfConcreteType<\cf3 OptionalSetterTarget\cf0 >().WithName(\cf6 "NoName"\cf0 );\par ??\par ?? \cf5 // The "Name" property is configured for this instance\par ??\cf0 r.ForConcreteType<\cf3 OptionalSetterTarget\cf0 >().Configure\par ?? .WithProperty(\cf6 "Name"\cf0 ).EqualTo(\cf6 "Jeremy"\cf0 );\par ?? \});\par ??\par ?? container.GetInstance<\cf3 OptionalSetterTarget\cf0 >().Name.ShouldEqual(\cf6 "Jeremy"\cf0 );\par ?? container.GetInstance<\cf3 OptionalSetterTarget\cf0 >(\cf6 "NoName"\cf0 ).Name.ShouldBeNull();\par ?? \}} --> - <div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"> +<div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> + [<span style="color: #2b91af;">Test</span>]/p> + <p style="margin: 0px;"> + <span style="color: blue;">public</span> + <span style="color: blue;">void</span> optional_setter_injection_with_string()</p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + + <span style="color: blue;">var</span> container = <span style="color: blue;">new</span> + <span style="color: #2b91af;">Container</span>(r =></p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + + <span style="color: green;">// The "Name" property is not configured for this + instance</span></p> + <p style="margin: 0px;"> + + r.InstanceOf<<span style="color: #2b91af;">OptionalSetterTarget</span>>().Is.OfConcreteType<<span + style="color: #2b91af;">OptionalSetterTarget</span>>().WithName(<span + style="color: #a31515;">"NoName"</span>);</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + + <span style="color: green;">// The "Name" property is configured for this + instance</span></p> + <p style="margin: 0px;"> + + r.ForConcreteType<<span style="color: #2b91af;">OptionalSetterTarget</span>>().Configure</p> + <p style="margin: 0px;"> + + .WithProperty(<span style="color: #a31515;">"Name"</span>).EqualTo(<span + style="color: #a31515;">"Jeremy"</span>);</p> + <p style="margin: 0px;"> + });</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + + container.GetInstance<<span style="color: #2b91af;">OptionalSetterTarget</span>>().Name.ShouldEqual(<span + style="color: #a31515;">"Jeremy"</span>);</p> + <p style="margin: 0px;"> + + container.GetInstance<<span style="color: #2b91af;">OptionalSetterTarget</span>>(<span + style="color: #a31515;">"NoName"</span>).Name.ShouldBeNull();</p> + <p style="margin: 0px;"> +& }</p> +</div> +<!--EndFragment--> +<p>In the case above I specified the value for the "Name" setter directly by + embedding the property value directly with the + WithProperty("Name").EqualTo("Jeremy"). You could also retrieve the value + for the property from the AppSettings portion of a .Net application config file + like this with the WithProperty("Name").EqualToAppSetting("name") syntax.</p> <!-- -{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs20 \cf3 public\cf0 \cf3 interface\cf0 \cf4 IDataProvider\cf0 \{\}\par ??\par ?? \cf3 public\cf0 \cf3 class\cf0 \cf4 Repository\par ??\cf0 \{\par ?? \cf3 private\cf0 \cf4 IDataProvider\cf0 _provider;\par ??\par ?? \cf3 public\cf0 \cf4 IDataProvider\cf0 Provider\par ?? \{\par ?? \cf3 set\par ??\cf0 \{\par ?? _provider = \cf3 value\cf0 ;\par ?? \}\par ?? \}\par ??\par ??\par ?? \cf3 public\cf0 \cf3 bool\cf0 ShouldCache \{ \cf3 get\cf0 ; \cf3 set\cf0 ; \}\par ?? \}} +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;\red0\green128\blue0;\red163\green21\blue21;}??\fs20 \cf3 var\cf0 container = \cf3 new\cf0 \cf4 Container\cf0 (r =>\par ?? \{\par ?? \cf5 // The "Name" property is configured for this instance\par ??\cf0 r.ForConcreteType<\cf4 OptionalSetterTarget\cf0 >().Configure\par ?? .WithProperty(\cf6 "Name"\cf0 ).EqualToAppSetting(\cf6 "name"\cf0 );\par ?? \});} --> - <div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"> - <p style="margin: 0px;"> - <span style="color: blue;">public</span> <span style="color: blue;">interface</span> - <span style="color: #2b91af;">IDataProvider</span>{}</p> - <p style="margin: 0px;"> - </p> - <p style="margin: 0px;"> +<div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> + + <span style="color: blue;">var</span> container = <span style="color: blue;">new</span> + <span style="color: #2b91af;">Container</span>(r =></p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + + r.ForConcreteType<<span style="color: #2b91af;">OptionalSetterTarget</span>>().Configure</p> + <p style="margin: 0px;"> + + .WithProperty(<span style="color: #a31515;">"Name"</span>).EqualToAppSetting(<span + style="color: #a31515;">"name"</span>);</p> + <p style="margin: 0px;"> + });</p> +</div> +<!--EndFragment--> +<p>In both of the cases above the property name is designated by a string. + Using strings to designate property names is always going to be somewhat + problematic, so there's a new option in 2.5 to specify property values with a + Lambda expression (inspired by + <a href="http://www.udidahan.com/2008/06/13/external-value-configuration-with-ioc/"> + this post from Udi Dahan</a>) using an Action<T>.</p> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red43\green145\blue175;\red163\green21\blue21;}??\fs20 r.ForConcreteType<\cf3 OptionalSetterTarget\cf0 >().Configure\par ?? .SetProperty(x => x.Name = \cf4 "Jeremy"\cf0 );} +--> +<div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> + + r.ForConcreteType<<span style="color: #2b91af;">OptionalSetterTarget</span>>().Configure</p> + <p style="margin: 0px;"> + + .SetProperty(x => x.Name = <span style="color: #a31515;">"Jeremy"</span>);</p> +</div> +<!--EndFragment--> +<p>The value of the Lamdba expression mechanism is that it makes the configuration + static-typed with all of the advantages that static typing brings. This + action is executed on the object after creation. Technically, this + mechanism can be used to do anything to the new object before StructureMap + returns the new object to the code that requested it. There is no + limitation to the number of Action<T> handlers you can use. </p> +<p> </p> +<h4>Configuring Setter Dependencies</h4> + <p>Let's say you have a class that has a public property for a singular dependency + and another public property for an array of dependencies.</p> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs20 \cf3 public\cf0 \cf3 class\cf0 \cf4 ClassWithDependency\par ??\cf0 \{\par ?? \cf3 public\cf0 \cf4 Rule\cf0 Rule \{ \cf3 get\cf0 ; \cf3 set\cf0 ; \}\par ?? \cf3 public\cf0 \cf4 Rule\cf0 [] Rules \{ \cf3 get\cf0 ; \cf3 set\cf0 ; \}\par ?? \}} +--> + <div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> <span style="color: blue;">public</span> <span style="color: blue;">class</span> - <span style="color: #2b91af;">Repository</span></p> - <p style="margin: 0px;"> + <span style="color: #2b91af;">ClassWithDependency</span></p> + <p style="margin: 0px;"> {</p> - <p style="margin: 0px;"> - <span style="color: blue;">private</span> - <span style="color: #2b91af;">IDataProvider</span> _provider;</p> - <p style="margin: 0px;"> - </p> - <p style="margin: 0px;"> + <p style="margin: 0px;"> <span style="color: blue;">public</span> - <span style="color: #2b91af;">IDataProvider</span> Provider</p> - <p style="margin: 0px;"> - {</p> - <p style="margin: 0px;"> - <span style="color: blue;">set</span></p> - <p style="margin: 0px;"> + <span style="color: #2b91af;">Rule</span> Rule { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</p> + <p style="margin: 0px;"> + <span style="color: blue;">public</span> + <span style="color: #2b91af;">Rule</span>[] Rules { <span style="color: blue;"> + get</span>; <span style="color: blue;">set</span>; }</p> + <p style="margin: 0px;"> +& }</p> + </div> +<!--EndFragment--> +<p>I can explicitly configure what gets injected into the "Rule" property for a + specific Instance of ClassWithDependency like this with the + .SetterDependency<T>() method that will look for the first public setter of type + T:</p> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red43\green145\blue175;\red0\green0\blue255;\red163\green21\blue21;}??\fs20 r.ForConcreteType<\cf3 ClassWithDependency\cf0 >().Configure\par ?? .SetterDependency<\cf3 Rule\cf0 >().Is(\cf4 new\cf0 \cf3 ColorRule\cf0 (\cf5 "Red"\cf0 ));} +--> + <div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> + + r.ForConcreteType<<span style="color: #2b91af;">ClassWithDependency</span>>().Configure</p> + <p style="margin: 0px;"> + + .SetterDependency<<span style="color: #2b91af;">Rule</span>>().Is(<span + style="color: blue;">new</span> <span style="color: #2b91af;">ColorRule</span>(<span + style="color: #a31515;">"Red"</span>));</p> +</div> +<!--EndFragment--> +<p>or for cases where a class may have multiple public setters of the same type, you + can specify the exact property with an Expression (.SetterDependency<T>( + expression ) ):</p> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;\red163\green21\blue21;}??\fs20 \cf3 var\cf0 container = \cf3 new\cf0 \cf4 Container\cf0 (r =>\par ?? \{\par ?? r.ForConcreteType<\cf4 ClassWithDependency\cf0 >().Configure\par ?? .SetterDependency<\cf4 Rule\cf0 >().Is(\cf3 new\cf0 \cf4 ColorRule\cf0 (\cf5 "Red"\cf0 ));\par ?? \});} +--> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;\red163\green21\blue21;}??\fs20 \cf3 var\cf0 container = \cf3 new\cf0 \cf4 Container\cf0 (r =>\par ?? \{\par ?? r.ForConcreteType<\cf4 ClassWithDependency\cf0 >().Configure\par ?? .SetterDependency<\cf4 Rule\cf0 >(x => x.Rule).Is(\cf3 new\cf0 \cf4 ColorRule\cf0 (\cf5 "Red"\cf0 ));\par ?? \});} +--> +<div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> + + <span style="color: blue;">var</span> container = <span style="color: blue;">new</span> + <span style="color: #2b91af;">Container</span>(r =></p> + <p style="margin: 0px;"> {</p> - <p style="margin: 0px;"> - _provider - = <span style="color: blue;">value</span>;</p> - <p style="margin: 0px;"> - }</p> - <p style="margin: 0px;"> - }</p> - <p style="margin: 0px;"> - </p> - <p style="margin: 0px;"> - </p> - <p style="margin: 0px;"> + <p style="margin: 0px;"> + + r.ForConcreteType<<span style="color: #2b91af;">ClassWithDependency</span>>().Configure</p> + <p style="margin: 0px;"> + + .SetterDependency<<span style="color: #2b91af;">Rule</span>>(x => x.Rule).Is(<span + style="color: blue;">new</span> <span style="color: #2b91af;">ColorRule</span>(<span + style="color: #a31515;">"Red"</span>));</p> + <p style="margin: 0px;"> + });</p> +</div> +<!--EndFragment--> +<p> </p> +<h4>"Auto Filling" a Setter Dependency</h4> +<p>Sometimes all you want to do is to simply say "fill in this property for me." + That's what the code below does for the "Rule" property with the + .SetterDependency<Rule>().IsTheDefault() syntax:</p> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;\red163\green21\blue21;}??\fs20 \cf3 var\cf0 container = \cf3 new\cf0 \cf4 Container\cf0 (r =>\par ?? \{\par ?? r.ForConcreteType<\cf4 ClassWithDependency\cf0 >().Configure\par ?? .SetterDependency<\cf4 Rule\cf0 >().IsTheDefault();\par ??\par ?? r.ForRequestedType<\cf4 Rule\cf0 >().TheDefault.Is.Object(\cf3 new\cf0 \cf4 ColorRule\cf0 (\cf5 "Green"\cf0 ));\par ?? \});} +--> +<div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> + + <span style="color: blue;">var</span> container = <span style="color: blue;">new</span> + <span style="color: #2b91af;">Container</span>(r =></p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + + r.ForConcreteType<<span style="color: #2b91af;">ClassWithDependency</span>>().Configure</p> + <p style="margin: 0px;"> + + .SetterDependency<<span style="color: #2b91af;">Rule</span>>().IsTheDefault();</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + + r.ForRequestedType<<span style="color: #2b91af;">Rule</span>>().TheDefault.Is.Object(<span + style="color: blue;">new</span> <span style="color: #2b91af;">ColorRule</span>(<span + style="color: #a31515;">"Green"</span>));</p> + <p style="margin: 0px;"> + });</p> +</div> +<!--EndFragment--> +<p>For certain dependency types you might want StructureMap to automatically fill + any public property of that type. The first usage that comes to mind is + logging. Let's say that we have an interface for our logging support + called ILogger. We can specify that any concrete class that has a public + property for the ILogger type will be filled in construction with code like this + (FillAllPropertiesOfType<ILogger>()):</p> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs20 \cf3 var\cf0 container = \cf3 new\cf0 \cf4 Container\cf0 (r =>\par ?? \{\par ?? r.FillAllPropertiesOfType<\cf4 ILogger\cf0 >().TheDefault.Is\par ?? .ConstructedBy(context => \cf3 new\cf0 \cf4 Logger\cf0 (context.ParentType));\par ?? \});} +--> +<div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> + + <span style="color: blue;">var</span> container = <span style="color: blue;">new</span> + <span style="color: #2b91af;">Container</span>(r =></p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + + r.FillAllPropertiesOfType<<span style="color: #2b91af;">ILogger</span>>().TheDefault.Is</p> + <p style="margin: 0px;"> + + .ConstructedBy(context => <span style="color: blue;">new</span> + <span style="color: #2b91af;">Logger</span>(context.ParentType));</p> + <p style="margin: 0px;"> + });</p> +</div> +<!--EndFragment--> +<p>Now, if I have some classes like:</p> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs20 \cf3 public\cf0 \cf3 class\cf0 \cf4 ClassWithLogger\par ??\cf0 \{\par ?? \cf3 public\cf0 \cf4 ILogger\cf0 Logger \{ \cf3 get\cf0 ; \cf3 set\cf0 ; \}\par ?? \}\par ??\par ?? \cf3 public\cf0 \cf3 class\cf0 \cf4 ClassWithLogger2\par ??\cf0 \{\par ?? \cf3 public\cf0 \cf4 ILogger\cf0 Logger \{ \cf3 get\cf0 ; \cf3 set\cf0 ; \}\par ?? \}} +--> +<div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> + <span style="color: blue;">public</span> <span style="color: blue;"> + class</span> <span style="color: #2b91af;">ClassWithLogger</span></p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> <span style="color: blue;">public</span> - <span style="color: blue;">bool</span> ShouldCache { <span style="color: blue;"> - get</span>; <span style="color: blue;">set</span>; }</p> - <p style="margin: 0px;"> + <span style="color: #2b91af;">ILogger</span> Logger { <span style="color: blue;"> + get</span>; <span style="color: blue;">set</span>; }</p> + <p style="margin: 0px;"> }</p> - </div> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + <span style="color: blue;">public</span> <span style="color: blue;"> + class</span> <span style="color: #2b91af;">ClassWithLogger2</span></p> + <p style="margin: 0px;"> + {</p> + <p style="margin: 0px;"> + <span style="color: blue;">public</span> + <span style="color: #2b91af;">ILogger</span> Logger { <span style="color: blue;"> + get</span>; <span style="color: blue;">set</span>; }</p> + <p style="margin: 0px;"> + }</p> +</div> <!--EndFragment--> -<p style="margin: 0px;"> - </p> - </div> -<!--EndFragment--> +<p>Now, when StructureMap builds new instances of these classes above the Logger + properties will be filled automatically without any explicit configuration for + either type. Here's a sample from the unit tests that constructs objects + of both ClassWithLogger and ClassWithLogger2 and verifies that the "Logger" + property was filled for both types without any further configuration.</p> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red43\green145\blue175;\red0\green0\blue255;}??\fs20 \par ?? container.GetInstance<\cf3 ClassWithLogger\cf0 >().Logger.ShouldBeOfType<\cf3 Logger\cf0 >().Type.ShouldEqual(\cf4 typeof\cf0 (\cf3 ClassWithLogger\cf0 ));\par ?? container.GetInstance<\cf3 ClassWithLogger2\cf0 >().Logger.ShouldBeOfType<\cf3 Logger\cf0 >().Type.ShouldEqual(\cf4 typeof\cf0 (\cf3 ClassWithLogger2\cf0 ));\par ??} +--> +<div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> + + container.GetInstance<<span style="color: #2b91af;">ClassWithLogger</span>>().Logger.ShouldBeOfType<<span + style="color: #2b91af;">Logger</span>>();</p> + <p style="margin: 0px;"> + + container.GetInstance<<span style="color: #2b91af;">ClassWithLogger2</span>>().Logger.ShouldBeOfType<<span + style="color: #2b91af;">Logger</span>>();</p> + <p style="margin: 0px;"> + </p> </div> <!--EndFragment--> -<h4>Defining Setter Properties with Attributes</h4> -<p>Just use the [StructureMap.Attributes.SetterProperty] to denote properties that - need to be filled by StructureMap. If you despise scattering attributes in - your code, and the tight coupling </p> +<p> </p> + <!-- +{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs20 \cf3 public\cf0 \cf3 interface\cf0 \cf4 IDataProvider\cf0 \{\}\par ??\par ?? \cf3 public\cf0 \cf3 class\cf0 \cf4 Repository\par ??\cf0 \{\par ?? \cf3 private\cf0 \cf4 IDataProvider\cf0 _provider;\par ??\par ?? \cf3 public\cf0 \cf4 IDataProvider\cf0 Provider\par ?? \{\par ?? \cf3 set\par ??\cf0 \{\par ?? _provider = \cf3 value\cf0 ;\par ?? \}\par ?? \}\par ?? \}} +--> +<!--EndFragment--> +<h4>Defining Setter Properties with Attributes<p>Just use the [StructureMap.Attributes.SetterProperty] to denote properties that + need to be filled by StructureMap. Marking a property with the + [SetterProperty] makes the setter mandatory. StructureMap will throw an + exception if the "ShouldCache" property isn't specified for the concrete type + shown below. If the "Provider" property isn't explicitly configured, + StructureMap will use the default instance of IDataProvider for the "Provider" + property (or throw an exception if StructureMap doesn't know how to build the + type IDataProvider). </p> +<!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;\red0\green128\blue0;}??\fs20 \cf3 public\cf0 \cf3 class\cf0 \cf4 Repository\par ??\cf0 \{\par ?? \cf3 private\cf0 \cf4 IDataProvider\cf0 _provider;\par ??\par ?? \cf5 // Adding the SetterProperty to a setter directs\par ??\cf0 \cf5 // StructureMap to use this property when\par ??\cf0 \cf5 // constructing a Repository instance\par ??\cf0 [\cf4 SetterProperty\cf0 ]\par ?? \cf3 public\cf0 \cf4 IDataProvider\cf0 Provider\par ?? \{\par ?? \cf3 set\par ??\cf0 \{\par ?? _provider = \cf3 value\cf0 ;\par ?? \}\par ?? \}\par ??\par ?? [\cf4 SetterProperty\cf0 ]\par ?? \cf3 public\cf0 \cf3 bool\cf0 ShouldCache \{ \cf3 get\cf0 ; \cf3 set\cf0 ; \}\par ?? \}} --> <div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"> @@ -224,7 +489,7 @@ <span style="color: green;">// constructing a Repository instance</span></p> <p style="margin: 0px;"> - [<span style="color: #2b91af;">SetterProperty</span>]</p> + [<span style="color: #2b91af;">SetterProperty</span>]/p> <p style="margin: 0px;"> <span style="color: blue;">public</span> <span style="color: #2b91af;">IDataProvider</span> Provider</p> @@ -258,81 +523,124 @@ <h4>Defining Setter Properties in Xml</h4> <p>Setter properties can be defined in the Xml configuration by explicitly directing - StructureMap to use setter properties while building a concrete type. From + StructureMap to use setter properties while building a concrete type. In + the Xml, Setter configuration is done with the exact syntax as constructor + arguments. For example, the "Name" property of the OptionalSetterTarget + class shown in previous sections can be set just like a constructor argument in + an Xml node:</p> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue255;\red255\green255\blue255;\red163\green21\blue21;\red255\green0\blue0;\red0\green0\blue0;}??\fs20 \cf1 <\cf3 StructureMap\cf1 \cf4 MementoStyle\cf1 =\cf0 "\cf1 Attribute\cf0 "\cf1 >\par ?? <\cf3 DefaultInstance\par ??\cf1 \cf4 PluginType\cf1 =\cf0 "\cf1 StructureMap.Testing.Pipeline.OptionalSetterTarget, StructureMap.Testing\cf0 "\par ??\cf1 \cf4 PluggedType\cf1 =\cf0 "\cf1 StructureMap.Testing.Pipeline.OptionalSetterTarget, StructureMap.Testing\cf0 "\par ??\cf1 \cf4 Name\cf1 =\cf0 "\cf1 Jeremy\cf0 "\cf1 />\par ??</\cf3 StructureMap\cf1 >} +--> + <div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> + <span style="color: blue;"> <</span><span style="color: #a31515;">StructureMap</span><span + style="color: blue;"> </span><span style="color: red;">MementoStyle</span><span + style="color: blue;">=</span>"<span style="color: blue;">Attribute</span>"<span + style="color: blue;">> </span> + </p> + <p style="margin: 0px;"> + <span style="color: blue;"> <</span><span + style="color: #a31515;">DefaultInstance</span></p> + <p style="margin: 0px;"> + <span style="color: blue;"> </span> + <span style="color: red;">PluginType</span><span style="color: blue;">=</span>"<span + style="color: blue;">StructureMap.Testing.Pipeline.OptionalSetterTarget, + StructureMap.Testing</span>"</p> + <p style="margin: 0px;"> + <span style="color: blue;"> </span> + <span style="color: red;"> PluggedType</span><span style="color: blue;">=</span>"<span + style="color: blue;">StructureMap.Testing.Pipeline.OptionalSetterTarget, + StructureMap.Testing</span>"</p> + <p style="margin: 0px;"> + <span style="color: blue;"> </span> + <span style="color: red;"> Name</span><span style="color: blue;">=</span>"<span + style="color: blue;">Jeremy</span>"<span style="color: blue;"> /></span></p> + <p style="margin: 0px;"> + <span style="color: blue;"> </</span><span style="color: #a31515;">StructureMap</span><span + style="color: blue;">></span></p> + </div> +<!--EndFragment--> +<p> </p> +<p>Setter properties can also be designated as mandatory setters with the <Setter> + node in the Xml configuration. From the unit tests, I have a class called OtherGridColumn that exposes several properties:</p> <!-- {\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;\red163\green21\blue21;}??\fs20 \cf3 public\cf0 \cf3 class\cf0 \cf4 OtherGridColumn\cf0 : \cf4 IGridColumn\par ??\cf0 \{\par ?? \cf3 public\cf0 \cf4 IWidget\cf0 Widget \{ \cf3 get\cf0 ; \cf3 set\cf0 ; \}\par ??\par ?? \cf3 public\cf0 \cf3 string\cf0 ReadOnly\par ?? \{\par ?? \cf3 get\par ??\cf0 \{\par ?? \cf3 return\cf0 \cf5 "whatever"\cf0 ;\par ?? \}\par ?? \}\par ??\par ?? \cf3 public\cf0 \cf4 FontStyleEnum\cf0 FontStyle \{ \cf3 get\cf0 ; \cf3 set\cf0 ; \}\par ?? \cf3 public\cf0 \cf3 string\cf0 ColumnName \{ \cf3 get\cf0 ; \cf3 set\cf0 ; \}\par ?? \cf3 public\cf0 \cf4 Rule\cf0 [] Rules \{ \cf3 get\cf0 ; \cf3 set\cf0 ; \}\par ?? \cf3 public\cf0 \cf3 bool\cf0 WrapLines \{ \cf3 get\cf0 ; \cf3 set\cf0 ; \}\par ?? \cf3 public\cf0 \cf3 bool\cf0 Displayed \{ \cf3 get\cf0 ; \cf3 set\cf0 ; \}\par ?? \cf3 public\cf0 \cf3 int\cf0 Size \{ \cf3 get\cf0 ; \cf3 set\cf0 ; \}\par ?? \}} --> <div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"> - <p style="margin: 0px;"> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;\red163\green21\blue21;}??\fs20 \cf3 public\cf0 \cf3 class\cf0 \cf4 OtherGridColumn\cf0 : \cf4 IGridColumn\par ??\cf0 \{\par ?? \cf3 public\cf0 \cf4 IWidget\cf0 Widget \{ \cf3 get\cf0 ; \cf3 set\cf0 ; \}\par ??\par ?? \cf3 public\cf0 \cf3 string\cf0 ReadOnly\par ?? \{\par ?? \cf3 get\cf0 \{ \cf3 return\cf0 \cf5 "whatever"\cf0 ; \}\par ?? \}\par ??\par ?? \cf3 public\cf0 \cf4 FontStyleEnum\cf0 FontStyle \{ \cf3 get\cf0 ; \cf3 set\cf0 ; \}\par ?? \cf3 public\cf0 \cf3 string\cf0 ColumnName \{ \cf3 get\cf0 ; \cf3 set\cf0 ; \}\par ?? \cf3 public\cf0 \cf4 Rule\cf0 [] Rules \{ \cf3 get\cf0 ; \cf3 set\cf0 ; \}\par ?? \cf3 public\cf0 \cf3 bool\cf0 WrapLines \{ \cf3 get\cf0 ; \cf3 set\cf0 ; \}\par ?? \cf3 public\cf0 \cf3 bool\cf0 Displayed \{ \cf3 get\cf0 ; \cf3 set\cf0 ; \}\par ?? \cf3 public\cf0 \cf3 int\cf0 Size \{ \cf3 get\cf0 ; \cf3 set\cf0 ; \}\par ?? \}} +--> + <div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + <p style="margin: 0px;"> <span style="color: blue;">public</span> <span style="color: blue;">class</span> - <span style="color: #2b91af;">OtherGridColumn</span> : - <span style="color: #2b91af;">IGridColumn</span></p> - <p style="margin: 0px;"> + <span style="color: #2b91af;">OtherGridColumn</span> : + <span style="color: #2b91af;">IGridColumn</span></p> + <p style="margin: 0px;"> {</p> - <p style="margin: 0px;"> + <p style="margin: 0px;"> <span style="color: blue;">public</span> - <span style="color: #2b91af;">IWidget</span> Widget { <span style="color: blue;"> - get</span>; <span style="color: blue;">set</span>; }</p> - <p style="margin: 0px;"> - </p> - <p style="margin: 0px;"> + <span style="color: #2b91af;">IWidget</span> Widget { <span style="color: blue;"> + get</span>; <span style="color: blue;">set</span>; }</p> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> <span style="color: blue;">public</span> - <span style="color: blue;">string</span> ReadOnly</p> - <p style="margin: 0px;"> + <span style="color: blue;">string</span> ReadOnly</p> + <p style="margin: 0px;"> {</p> - <p style="margin: 0px;"> - - <span style="color: blue;">get</span></p> - <p style="margin: 0px;"> - {</p> - <p style="margin: 0px;"> - - <span style="color: blue;">return</span> <span style="color: #a31515;"> - "whatever"</span>;</p> - <p style="margin: 0px;"> - }</p> - <p style="margin: 0px;"> + <p style="margin: 0px;"> + <span style="color: blue;"> + get</span> { <span style="color: blue;">return</span> + <span style="color: #a31515;">"whatever"</span>; }</p> + <p style="margin: 0px;"> }</p> - <p style="margin: 0px;"> - </p> - <p style="margin: 0px;"> + <p style="margin: 0px;"> + </p> + <p style="margin: 0px;"> <span style="color: blue;">public</span> - <span style="color: #2b91af;">FontStyleEnum</span> FontStyle { - <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</p> - <p style="margin: 0px;"> + <span style="color: #2b91af;">FontStyleEnum</span> FontStyle { + <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</p> + <p style="margin: 0px;"> <span style="color: blue;">public</span> - <span style="color: blue;">string</span> ColumnName { <span style="color: blue;"> - get</span>; <span style="color: blue;">set</span>; }</p> - <p style="margin: 0px;"> + <span style="color: blue;">string</span> ColumnName { <span style="color: blue;"> + get</span>; <span style="color: blue;">set</span>; }</p> + <p style="margin: 0px;"> <span style="color: blue;">public</span> - <span style="color: #2b91af;">Rule</span>[] Rules { <span style="color: blue;"> - get</span>; <span style="color: blue;">set</span>; }</p> - <p style="margin: 0px;"> + <span style="color: #2b91af;">Rule</span>[] Rules { <span style="color: blue;"> + get</span>; <span style="color: blue;">set</span>; }</p> + <p style="margin: 0px;"> <span style="color: blue;">public</span> - <span style="color: blue;">bool</span> WrapLines { <span style="color: blue;"> - get</span>; <span style="color: blue;">set</span>; }</p> - <p style="margin: 0px;"> + <span style="color: blue;">bool</span> WrapLines { <span style="color: blue;"> + get</span>; <span style="color: blue;">set</span>; }</p> + <p style="margin: 0px;"> <span style="color: blue;">public</span> - <span style="color: blue;">bool</span> Displayed { <span style="color: blue;"> - get</span>; <span style="color: blue;">set</span>; }</p> - <p style="margin: 0px;"> + <span style="color: blue;">bool</span> Displayed { <span style="color: blue;"> + get</span>; <span style="color: blue;">set</span>; }</p> + <p style="margin: 0px;"> <span style="color: blue;">public</span> - <span style="color: blue;">int</span> Size { <span style="color: blue;">get</span>; - <span style="color: blue;">set</span>; }</p> - <p style="margin: 0px;"> + <span style="color: blue;">int</span> Size { <span style="color: blue;">get</span>; + <span style="color: blue;">set</span>; }</p> + <p style="margin: 0px;"> }</p> + </div> +<!--EndFragment--> +<p style="margin: 0px;"> + </p> </div> <!--EndFragment--> -<p>I can direct StructureMap to use these properties in a <Plugin> node for - OtherGridColumn.</p> +<p>I can direct StructureMap to make the properties on the OtherGridColumn class + mandatory in a <Plugin> node for + OtherGridColumn. This probably isn't necessary with the new optional + setter injection capabilities, but it is still valid and the equivalent of using + the [SetterProperty] attribute.</p> <!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue255;\red255\green255\blue255;\red163\green21\blue21;\red255\green0\blue0;\red0\green0\blue0;}??\fs20 \cf1 \tab <\cf3 PluginFamily\cf1 \cf4 Type\cf1 =\cf0 "\cf1 StructureMap.Testing.Widget5.IGridColumn\cf0 "\cf1 \cf4 Assembly\cf1 =\cf0 "\cf1 StructureMap.Testing.Widget5\cf0 "\cf1 \cf4 DefaultKey\cf1 =\cf0 ""\cf1 >\par ??\tab \tab <\cf3 Source\cf1 \cf4 Type\cf1 =\cf0 "\cf1 XmlFile\cf0 "\cf1 \cf4 FilePath\cf1 =\cf0 "\cf1 GridColumnInstances.xml\cf0 "\cf1 \cf4 XPath\cf1 =\cf0 "\cf1 //GridColumns\cf0 "\cf1 \cf4 NodeName\cf1 =\cf0 "\cf1 GridColumn\cf0 "\cf1 />\par ??\tab \tab <\cf3 Plugin\cf1 \cf4 Assembly\cf1 =\cf0 "\cf1 StructureMap.Testing.Widget5\cf0 "\cf1 \cf4 Type\cf1 =\cf0 "\cf1 StructureMap.Testing.Widget5.OtherGridColumn\cf0 "\cf1 \cf4 ConcreteKey\cf1 =\cf0 "\cf1 Other\cf0 "\cf1 >\par ??\tab \tab \tab <\cf3 Setter\cf1 \cf4 Name\cf1 =\cf0 "\cf1 ColumnName\cf0 "\cf1 />\par ??\tab \tab \tab <\cf3 Setter\cf1 \cf4 Name\cf1 =\cf0 "\cf1 FontStyle\cf0 "\cf1 />\par ??\tab \tab \tab <\cf3 Setter\cf1 \cf4 Name\cf1 =\cf0 "\cf1 Rules\cf0 "\cf1 />\par ??\tab \tab \tab <\cf3 Setter\cf1 \cf4 Name\cf1 =\cf0 "\cf1 Widget\cf0 "\cf1 />\par ??\tab \tab \tab <\cf3 Setter\cf1 \cf4 Name\cf1 =\cf0 "\cf1 WrapLines\cf0 "\cf1 />\par ??\tab \tab </\cf3 Plugin\cf1 >\par ??\tab </\cf3 PluginFamily\cf1 >} --> <div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"> <p style="margin: 0px;"> - <span style="color: blue;"> <</span><span style="color: #a31515;">PluginFamily</span><span + <span style="color: blue;"> <</span><span style="color: #a31515;">PluginFamily/span><span style="color: blue;"> </span><span style="color: red;">Type</span><span style="color: blue;">=</span>"<span style="color: blue;">StructureMap.Testing.Widget5.IGridColumn</span>"<span style="color: blue;"> </span><span style="color: red;">Assembly</span><span @@ -379,13 +687,10 @@ style="color: #a31515;">Plugin</span><span style="color: blue;">></span></p> <p style="margin: 0px;"> <span style="color: blue;"> </</span><span style="color: #a31515;">PluginFamily</span><span - style="color: blue;">></span></p> + style="color: blue;">&></span></p> </div> <!--EndFragment--> <p> </p> - <h4>Defining Setter Properties with the Fluent Interface</h4> - <p>This isn't possible today, except with a post processing method. This - feature will be added in the next minor release.</p> - </body> + </body> </html> \ No newline at end of file Added: trunk/Source/HTML/Example.xml =================================================================== --- trunk/Source/HTML/Example.xml (rev 0) +++ trunk/Source/HTML/Example.xml 2008-10-18 03:05:42 UTC (rev 184) @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8" ?> +<StructureMap MementoStyle="Attribute"> + <DefaultInstance + PluginType="StructureMap.Testing.Pipeline.OptionalSetterTarget, StructureMap.Testing" + PluggedType="StructureMap.Testing.Pipeline.OptionalSetterTarget, StructureMap.Testing" + Name="Jeremy" /> +</StructureMap> \ No newline at end of file Modified: trunk/Source/HTML/HTML.csproj =================================================================== --- trunk/Source/HTML/HTML.csproj 2008-10-17 19:00:37 UTC (rev 183) +++ trunk/Source/HTML/HTML.csproj 2008-10-18 03:05:42 UTC (rev 184) @@ -62,6 +62,7 @@ <Content Include="BestPractices.htm" /> <Content Include="ChangingDefaultsAtRuntime.htm" /> <Content Include="CompositeConfiguration.htm" /> + <Content Include="Example.xml" /> <Content Include="Glossary.htm" /> <Content Include="ConcreteTypes.htm" /> <Content Include="ConfigurationArchitecture.htm" /> Modified: trunk/Source/HTML/ScanningAssemblies.htm =================================================================== --- trunk/Source/HTML/ScanningAssemblies.htm 2008-10-17 19:00:37 UTC (rev 183) +++ trunk/Source/HTML/ScanningAssemblies.htm 2008-10-18 03:05:42 UTC (rev 184) @@ -1,9 +1,406 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> - <title></title> + <title>Auto Registration with Type Scanning</title> </head> <body> - + <h1>Auto Registration with Type Scanning</h1> + + <p> + StructureMap has always had some ability to register types by by scanning + assemblies (auto registration). The original version of StructureMap circa + 2004 looked for types decorated with specific attributes. Version 2.0 + added the ability to look for Registry classes within those assemblies. + The auto registration mechanism has been completely revamped in StructureMap 2.5 + with greatly extended capabilities. The downside is that the "scanning" + syntax in v2.5 is completely incompatible with previous versions, including the + 2.4.9 preview release. However, the Xml configuration has remained + consistent in both form and function.</p> + <h4> + Table of Contents</h4> + <ul> + <li>The Scan() Expression</li> + </ul> + <h4> + Using the Scan() Expression</h4> + <p> + Auto registration begins with the Scan() expression inside a Registry class or + the now deprecated StructureMapConfiguration class. Here's an example from + my current project:</p> +<!-- +{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red43\green145\blue175;}??\fs20 Scan(x =>\par ?? \{\par ?? x.TheCallingAssembly();\par ??\par ?? x.ExcludeNamespaceContainingType<\cf3 IEvent\cf0 >();\par ?? x.ExcludeNamespaceContainingType<\cf3 SearchModel\cf0 >();\par ?? x.ExcludeNamespaceContainingType<\cf3 AuthenticationService\cf0 >();\par ?? x.ExcludeNamespaceContainingType<\cf3 DovetailController\cf0 >();\par ??\par ?? x.AddAllTypesOf<\cf3 IDomainMap\cf0 >();\par ?? \par ?? x.WithDefaultConventions();\par ?? x.With<\cf3 DomainEntityAliaser\cf0 >();\par ?? \});} +--> + <div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: black thin solid;"> + ... [truncated message content] |
From: <fli...@us...> - 2008-10-17 19:00:42
|
Revision: 183 http://structuremap.svn.sourceforge.net/structuremap/?rev=183&view=rev Author: flimflan Date: 2008-10-17 19:00:37 +0000 (Fri, 17 Oct 2008) Log Message: ----------- Added ability to provide a default value to EqualToAppSetting if the appSetting key does not exist Modified Paths: -------------- trunk/Source/StructureMap/Pipeline/PropertyExpression.cs trunk/Source/StructureMap.Testing/Configuration/DSL/AddInstanceTester.cs Modified: trunk/Source/StructureMap/Pipeline/PropertyExpression.cs =================================================================== --- trunk/Source/StructureMap/Pipeline/PropertyExpression.cs 2008-10-17 14:40:26 UTC (rev 182) +++ trunk/Source/StructureMap/Pipeline/PropertyExpression.cs 2008-10-17 19:00:37 UTC (rev 183) @@ -31,13 +31,26 @@ /// Sets the value of the constructor argument to the key/value in the /// AppSettings /// </summary> - /// <param name="appSettingKey"></param> + /// <param name="appSettingKey">The key in appSettings for the value to use.</param> /// <returns></returns> public T EqualToAppSetting(string appSettingKey) { + return EqualToAppSetting(appSettingKey, null); + } + + /// <summary> + /// Sets the value of the constructor argument to the key/value in the + /// AppSettings when it exists. Otherwise uses the provided default value. + /// </summary> + /// <param name="appSettingKey">The key in appSettings for the value to use.</param> + /// <param name="defaultValue">The value to use if an entry for <paramref name="appSettingKey"/> does not exist in the appSettings section.</param> + /// <returns></returns> + public T EqualToAppSetting(string appSettingKey, string defaultValue) + { string propertyValue = ConfigurationManager.AppSettings[appSettingKey]; + if (propertyValue == null) propertyValue = defaultValue; _instance.SetProperty(_propertyName, propertyValue); - return (T) _instance; + return (T)_instance; } } } \ No newline at end of file Modified: trunk/Source/StructureMap.Testing/Configuration/DSL/AddInstanceTester.cs =================================================================== --- trunk/Source/StructureMap.Testing/Configuration/DSL/AddInstanceTester.cs 2008-10-17 14:40:26 UTC (rev 182) +++ trunk/Source/StructureMap.Testing/Configuration/DSL/AddInstanceTester.cs 2008-10-17 19:00:37 UTC (rev 183) @@ -35,7 +35,13 @@ .WithName("AppSetting") .WithProperty("color").EqualToAppSetting("Color"); + // Pull a property from the App config + registry.InstanceOf<IWidget>() + .Is.OfConcreteType<NotPluggableWidget>() + .WithName("UsesDefaultValue") + .WithProperty("name").EqualToAppSetting("WidgetName", "TheDefaultValue"); + registry.InstanceOf<IWidget>().Is.OfConcreteType<AWidget>(); }); } @@ -71,7 +77,7 @@ .Widget.IsType<AWidget>(); } - [Test, Explicit] + [Test] public void CreateAnInstancePullAPropertyFromTheApplicationConfig() { Assert.AreEqual("Blue", ConfigurationManager.AppSettings["Color"]); @@ -80,6 +86,14 @@ } [Test] + public void CreateAnInstanceUsingDefaultPropertyValueWhenSettingDoesNotExistInApplicationConfig() + { + Assert.AreEqual(null, ConfigurationManager.AppSettings["WidgetName"]); + var widget = (NotPluggableWidget)container.GetInstance<IWidget>("UsesDefaultValue"); + Assert.AreEqual("TheDefaultValue", widget.Name); + } + + [Test] public void SimpleCaseWithNamedInstance() { container = new Container( This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fli...@us...> - 2008-10-17 14:40:39
|
Revision: 182 http://structuremap.svn.sourceforge.net/structuremap/?rev=182&view=rev Author: flimflan Date: 2008-10-17 14:40:26 +0000 (Fri, 17 Oct 2008) Log Message: ----------- - Added ability to scan all assemblies in a path of the file system. - Now includes the .pdb and intellisense .xml in the build output Modified Paths: -------------- trunk/Source/StructureMap/Graph/AssemblyScanner.cs trunk/Source/StructureMap/StructureMap.csproj trunk/Source/StructureMap.Testing/Graph/AssemblyScannerTester.cs trunk/cruise.build Modified: trunk/Source/StructureMap/Graph/AssemblyScanner.cs =================================================================== --- trunk/Source/StructureMap/Graph/AssemblyScanner.cs 2008-10-10 21:11:00 UTC (rev 181) +++ trunk/Source/StructureMap/Graph/AssemblyScanner.cs 2008-10-17 14:40:26 UTC (rev 182) @@ -227,5 +227,33 @@ { Exclude(type => type == typeof (T)); } + + public void AssembliesFromPath(string path) + { + AssembliesFromPath(path, a => true); + } + + public void AssembliesFromPath(string path, Predicate<Assembly> assemblyFilter) + { + var assemblyPaths = System.IO.Directory.GetFiles(path).Where(file => + System.IO.Path.GetExtension(file).Equals( + ".exe", StringComparison.OrdinalIgnoreCase) + || + System.IO.Path.GetExtension(file).Equals( + ".dll", StringComparison.OrdinalIgnoreCase)); + + foreach (var assemblyPath in assemblyPaths) + { + Assembly assembly = null; + try + { + assembly = System.Reflection.Assembly.LoadFrom(assemblyPath); + } + catch + { + } + if (assembly != null && assemblyFilter(assembly)) Assembly(assembly); + } + } } } \ No newline at end of file Modified: trunk/Source/StructureMap/StructureMap.csproj =================================================================== --- trunk/Source/StructureMap/StructureMap.csproj 2008-10-10 21:11:00 UTC (rev 181) +++ trunk/Source/StructureMap/StructureMap.csproj 2008-10-17 14:40:26 UTC (rev 182) @@ -75,9 +75,8 @@ <ConfigurationOverrideFile> </ConfigurationOverrideFile> <DefineConstants>TRACE</DefineConstants> - <DocumentationFile> - </DocumentationFile> - <DebugSymbols>false</DebugSymbols> + <DocumentationFile>bin\Release\StructureMap.XML</DocumentationFile> + <DebugSymbols>true</DebugSymbols> <FileAlignment>4096</FileAlignment> <NoStdLib>false</NoStdLib> <NoWarn> @@ -87,7 +86,7 @@ <RemoveIntegerChecks>false</RemoveIntegerChecks> <TreatWarningsAsErrors>false</TreatWarningsAsErrors> <WarningLevel>4</WarningLevel> - <DebugType>none</DebugType> + <DebugType>pdbonly</DebugType> <ErrorReport>prompt</ErrorReport> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Build|AnyCPU' "> Modified: trunk/Source/StructureMap.Testing/Graph/AssemblyScannerTester.cs =================================================================== --- trunk/Source/StructureMap.Testing/Graph/AssemblyScannerTester.cs 2008-10-10 21:11:00 UTC (rev 181) +++ trunk/Source/StructureMap.Testing/Graph/AssemblyScannerTester.cs 2008-10-17 14:40:26 UTC (rev 182) @@ -1,8 +1,10 @@ using System; +using System.IO; using NUnit.Framework; using StructureMap.Configuration.DSL; using StructureMap.Graph; using StructureMap.Testing.Widget; +using System.Linq; using StructureMap.Testing.Widget5; namespace StructureMap.Testing.Graph @@ -29,17 +31,32 @@ { #region Setup/Teardown + [TestFixtureSetUp] + public void FixtureSetUp() + { + var binFolder = Path.GetDirectoryName(GetType().Assembly.Location); + assemblyScanningFolder = Path.Combine(binFolder, "DynamicallyLoaded"); + if (!Directory.Exists(assemblyScanningFolder)) Directory.CreateDirectory(assemblyScanningFolder); + + var assembly1 = typeof (RedGreenRegistry).Assembly.Location; + var assembly2 = typeof(Widget3.IWorker).Assembly.Location; + + File.Copy(assembly1, Path.Combine(assemblyScanningFolder, Path.GetFileName(assembly1)), true); + File.Copy(assembly2, Path.Combine(assemblyScanningFolder, Path.GetFileName(assembly2)), true); + } + [SetUp] public void SetUp() { TestingRegistry.Reset(); - + theGraph = null; } #endregion private PluginGraph theGraph; + private string assemblyScanningFolder; private void Scan(Action<AssemblyScanner> action) { @@ -57,9 +74,22 @@ private void shouldNotHaveFamily<T>() { - theGraph.PluginFamilies.Contains(typeof (T)).ShouldBeFalse(); + theGraph.PluginFamilies.Contains(typeof(T)).ShouldBeFalse(); } + + private void shouldHaveFamilyWithSameName<T>() + { + // The Types may not be "Equal" if their assemblies were loaded in different load contexts (.LoadFrom) + // so we will consider them equal if their names match. + theGraph.PluginFamilies.Any(family => family.PluginType.FullName == typeof (T).FullName).ShouldBeTrue(); + } + + private void shouldNotHaveFamilyWithSameName<T>() + { + theGraph.PluginFamilies.Any(family => family.PluginType.FullName == typeof(T).FullName).ShouldBeFalse(); + } + [Test] public void AssemblyScanner_will_scan_for_attributes_by_default() { @@ -111,6 +141,24 @@ } [Test] + public void scan_all_assemblies_in_a_folder() + { + Scan(x => x.AssembliesFromPath(assemblyScanningFolder) ); + shouldHaveFamilyWithSameName<IInterfaceInWidget5>(); + shouldHaveFamilyWithSameName<Widget3.IWorker>(); + } + + [Test] + public void scan_specific_assemblies_in_a_folder() + { + var assemblyToSpecificallyExclude = typeof(Widget3.IWorker).Assembly.GetName().Name; + Scan(x => x.AssembliesFromPath(assemblyScanningFolder, asm => asm.GetName().Name != assemblyToSpecificallyExclude)); + + shouldHaveFamilyWithSameName<IInterfaceInWidget5>(); + shouldNotHaveFamilyWithSameName<Widget3.IWorker>(); + } + + [Test] public void test_the_family_attribute_scanner() { var scanner = new FamilyAttributeScanner(); Modified: trunk/cruise.build =================================================================== --- trunk/cruise.build 2008-10-10 21:11:00 UTC (rev 181) +++ trunk/cruise.build 2008-10-17 14:40:26 UTC (rev 182) @@ -69,6 +69,7 @@ <fileset basedir="source\"> <include name="**\bin\${project.config}\*.dll" /> <include name="**\bin\${project.config}\*.exe" /> + <include name="**\bin\${project.config}\*.pdb" /> <include name="**\bin\${project.config}\*.xml" /> <include name="**\bin\${project.config}\*.xml.actual" /> <include name="StructureMap.Testing\*.config" /> @@ -126,6 +127,7 @@ <fileset basedir="${build.dir}"> <include name="*.xml" /> <include name="*.config" /> + <exclude name="structuremap.xml" /> </fileset> </delete> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fli...@us...> - 2008-10-10 21:11:07
|
Revision: 181 http://structuremap.svn.sourceforge.net/structuremap/?rev=181&view=rev Author: flimflan Date: 2008-10-10 21:11:00 +0000 (Fri, 10 Oct 2008) Log Message: ----------- Enabled non-generic GetAllInstances with explicit arguments. Modified Paths: -------------- trunk/Source/StructureMap/Container.cs trunk/Source/StructureMap/ExplicitArgsExpression.cs trunk/Source/StructureMap/IContainer.cs trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj Added Paths: ----------- trunk/Source/StructureMap.Testing/Graph/TestExplicitArguments.cs Removed Paths: ------------- trunk/Source/StructureMap.Testing/Graph/ExplicitArgumentTester.cs Modified: trunk/Source/StructureMap/Container.cs =================================================================== --- trunk/Source/StructureMap/Container.cs 2008-10-08 20:38:53 UTC (rev 180) +++ trunk/Source/StructureMap/Container.cs 2008-10-10 21:11:00 UTC (rev 181) @@ -91,6 +91,15 @@ return session.CreateInstance(type, instance); } + public IList GetAllInstances(Type type, ExplicitArguments args) + { + BuildSession session = withNewSession(); + + args.RegisterDefaults(session); + + return forType(type).GetAllInstances(session); + } + public IList<T> GetAllInstances<T>(ExplicitArguments args) { BuildSession session = withNewSession(); Modified: trunk/Source/StructureMap/ExplicitArgsExpression.cs =================================================================== --- trunk/Source/StructureMap/ExplicitArgsExpression.cs 2008-10-08 20:38:53 UTC (rev 180) +++ trunk/Source/StructureMap/ExplicitArgsExpression.cs 2008-10-10 21:11:00 UTC (rev 181) @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using StructureMap.Pipeline; @@ -77,5 +78,11 @@ { return _container.GetAllInstances<T>(_args); } + + public IList GetAllInstances(Type type) + { + return _container.GetAllInstances(type, _args); + } + } } \ No newline at end of file Modified: trunk/Source/StructureMap/IContainer.cs =================================================================== --- trunk/Source/StructureMap/IContainer.cs 2008-10-08 20:38:53 UTC (rev 180) +++ trunk/Source/StructureMap/IContainer.cs 2008-10-10 21:11:00 UTC (rev 181) @@ -61,6 +61,7 @@ /// <returns></returns> object GetInstance(Type pluginType, string instanceKey); + IList GetAllInstances(Type type, ExplicitArguments args); IList<T> GetAllInstances<T>(ExplicitArguments args); T GetInstance<T>(ExplicitArguments args); Deleted: trunk/Source/StructureMap.Testing/Graph/ExplicitArgumentTester.cs =================================================================== --- trunk/Source/StructureMap.Testing/Graph/ExplicitArgumentTester.cs 2008-10-08 20:38:53 UTC (rev 180) +++ trunk/Source/StructureMap.Testing/Graph/ExplicitArgumentTester.cs 2008-10-10 21:11:00 UTC (rev 181) @@ -1,415 +0,0 @@ -using System.Collections.Generic; -using NUnit.Framework; -using StructureMap.Pipeline; -using StructureMap.Testing.Pipeline; - -namespace StructureMap.Testing.Graph -{ - [TestFixture] - public class ExplicitArgumentTester - { - #region Setup/Teardown - - [SetUp] - public void SetUp() - { - ObjectFactory.Initialize(x => { x.UseDefaultStructureMapConfigFile = false; }); - } - - #endregion - - public interface IExplicitTarget - { - } - - public class RedTarget : IExplicitTarget - { - } - - public class GreenTarget : IExplicitTarget - { - } - - public class ExplicitTarget : IExplicitTarget - { - private readonly string _name; - private readonly IProvider _provider; - - public ExplicitTarget(string name, IProvider provider) - { - _name = name; - _provider = provider; - } - - - public string Name - { - get { return _name; } - } - - public IProvider Provider - { - get { return _provider; } - } - } - - public interface IProvider - { - } - - public class RedProvider : IProvider - { - } - - public class BlueProvider : IProvider - { - } - - [Test] - public void Example() - { - IContainer container = new Container(); - var theTrade = new Trade(); - - var view = container.With(theTrade).GetInstance<TradeView>(); - - view.Trade.ShouldBeTheSameAs(theTrade); - } - - [Test] - public void Explicit_services_are_used_throughout_the_object_graph() - { - var theTrade = new Trade(); - - IContainer container = new Container(r => - { - r.ForRequestedType<IView>().TheDefaultIsConcreteType<TradeView>(); - r.ForRequestedType<Node>().TheDefaultIsConcreteType<TradeNode>(); - }); - - var command = container.With(theTrade).GetInstance<Command>(); - - command.Trade.ShouldBeTheSameAs(theTrade); - command.Node.IsType<TradeNode>().Trade.ShouldBeTheSameAs(theTrade); - command.View.IsType<TradeView>().Trade.ShouldBeTheSameAs(theTrade); - } - - [Test] - public void ExplicitArguments_can_return_child_by_name() - { - var args = new ExplicitArguments(); - var theNode = new Node(); - args.SetArg("node", theNode); - - IConfiguredInstance instance = new ExplicitInstance(typeof (Command), args, null); - - Assert.AreSame(theNode, instance.GetChild("node", typeof (Node), new StubBuildSession())); - } - - [Test] - public void Fill_in_argument_by_name() - { - var container = new Container(); - container.SetDefault<IView, View>(); - - var theNode = new Node(); - var theTrade = new Trade(); - - var command = container - .With("node").EqualTo(theNode) - .With(theTrade) - .GetInstance<Command>(); - - Assert.IsInstanceOfType(typeof (View), command.View); - Assert.AreSame(theNode, command.Node); - Assert.AreSame(theTrade, command.Trade); - } - - [Test] - public void NowDoItWithObjectFactoryItself() - { - ObjectFactory.Initialize(x => - { - x.ForConcreteType<ExplicitTarget>().Configure - .CtorDependency<IProvider>().Is<RedProvider>() - .WithCtorArg("name").EqualTo("Jeremy"); - }); - - // Get the ExplicitTarget without setting an explicit arg for IProvider - var firstTarget = ObjectFactory.GetInstance<ExplicitTarget>(); - Assert.IsInstanceOfType(typeof (RedProvider), firstTarget.Provider); - - // Now, set the explicit arg for IProvider - var theBlueProvider = new BlueProvider(); - var secondTarget = ObjectFactory.With<IProvider>(theBlueProvider).GetInstance<ExplicitTarget>(); - Assert.AreSame(theBlueProvider, secondTarget.Provider); - } - - [Test] - public void NowDoItWithObjectFactoryItself_with_new_API() - { - ObjectFactory.Initialize(x => - { - x.ForRequestedType<ExplicitTarget>().TheDefault.Is.OfConcreteType<ExplicitTarget>() - .CtorDependency<IProvider>().Is(child => child.OfConcreteType<RedProvider>()) - .WithCtorArg("name").EqualTo("Jeremy"); - }); - - // Get the ExplicitTarget without setting an explicit arg for IProvider - ObjectFactory.GetInstance<ExplicitTarget>().Provider.IsType<RedProvider>(); - - // Now, set the explicit arg for IProvider - var theBlueProvider = new BlueProvider(); - ObjectFactory.With<IProvider>(theBlueProvider).GetInstance<ExplicitTarget>() - .Provider.ShouldBeTheSameAs(theBlueProvider); - } - - [Test] - public void OverrideAPrimitiveWithObjectFactory() - { - ObjectFactory.Initialize(x => - { - x.ForConcreteType<ExplicitTarget>().Configure - .CtorDependency<IProvider>().Is<RedProvider>() - .WithCtorArg("name").EqualTo("Jeremy"); - }); - - // Get the ExplicitTarget without setting an explicit arg for IProvider - var firstTarget = ObjectFactory.GetInstance<ExplicitTarget>(); - Assert.AreEqual("Jeremy", firstTarget.Name); - - // Now, set the explicit arg for IProvider - var secondTarget = ObjectFactory.With("name").EqualTo("Julia").GetInstance<ExplicitTarget>(); - Assert.AreEqual("Julia", secondTarget.Name); - } - - [Test] - public void pass_explicit_service_into_all_instances() - { - // The Container is constructed with 2 instances - // of TradeView - var container = new Container(r => - { - r.ForRequestedType<TradeView>() - .TheDefaultIsConcreteType<TradeView>() - .AddConcreteType<SecuredTradeView>(); - }); - - var theTrade = new Trade(); - - IList<TradeView> views = container.With(theTrade).GetAllInstances<TradeView>(); - - views[0].Trade.ShouldBeTheSameAs(theTrade); - views[1].Trade.ShouldBeTheSameAs(theTrade); - } - - [Test] - public void Pass_in_arguments_as_dictionary() - { - var manager = new Container(); - manager.SetDefault<IView, View>(); - - var theNode = new Node(); - var theTrade = new Trade(); - - var args = new ExplicitArguments(); - args.Set(theNode); - args.SetArg("trade", theTrade); - - var command = manager.GetInstance<Command>(args); - - Assert.IsInstanceOfType(typeof (View), command.View); - Assert.AreSame(theNode, command.Node); - Assert.AreSame(theTrade, command.Trade); - } - - - [Test] - public void PassAnArgumentIntoExplicitArgumentsForARequestedInterface() - { - IContainer manager = - new Container( - registry => registry.ForRequestedType<IProvider>().TheDefaultIsConcreteType<LumpProvider>()); - - var args = new ExplicitArguments(); - var theLump = new Lump(); - args.Set(theLump); - - var instance = (LumpProvider) manager.GetInstance<IProvider>(args); - Assert.AreSame(theLump, instance.Lump); - } - - [Test] - public void PassAnArgumentIntoExplicitArgumentsForARequestedInterfaceUsingObjectFactory() - { - ObjectFactory.Initialize(x => { x.ForRequestedType<IProvider>().TheDefaultIsConcreteType<LumpProvider>(); }); - - - var theLump = new Lump(); - - var provider = (LumpProvider) ObjectFactory.With(theLump).GetInstance<IProvider>(); - Assert.AreSame(theLump, provider.Lump); - } - - [Test] - public void PassAnArgumentIntoExplicitArgumentsThatMightNotAlreadyBeRegistered() - { - var theLump = new Lump(); - var provider = ObjectFactory.With(theLump).GetInstance<LumpProvider>(); - Assert.AreSame(theLump, provider.Lump); - } - - [Test] - public void PassExplicitArgsIntoInstanceManager() - { - var container = new Container(r => - { - r.ForConcreteType<ExplicitTarget>().Configure - .CtorDependency<IProvider>().Is<RedProvider>() - .WithCtorArg("name").EqualTo("Jeremy"); - }); - - var args = new ExplicitArguments(); - - // Get the ExplicitTarget without setting an explicit arg for IProvider - var firstTarget = container.GetInstance<ExplicitTarget>(args); - Assert.IsInstanceOfType(typeof (RedProvider), firstTarget.Provider); - - // Now, set the explicit arg for IProvider - args.Set<IProvider>(new BlueProvider()); - var secondTarget = container.GetInstance<ExplicitTarget>(args); - Assert.IsInstanceOfType(typeof (BlueProvider), secondTarget.Provider); - } - - [Test] - public void RegisterAndFindServicesOnTheExplicitArgument() - { - var args = new ExplicitArguments(); - Assert.IsNull(args.Get<IProvider>()); - - var red = new RedProvider(); - args.Set<IProvider>(red); - - Assert.AreSame(red, args.Get<IProvider>()); - - args.Set<IExplicitTarget>(new RedTarget()); - Assert.IsInstanceOfType(typeof (RedTarget), args.Get<IExplicitTarget>()); - } - - [Test] - public void RegisterAndRetrieveArgs() - { - var args = new ExplicitArguments(); - Assert.IsNull(args.GetArg("name")); - - args.SetArg("name", "Jeremy"); - Assert.AreEqual("Jeremy", args.GetArg("name")); - - args.SetArg("age", 34); - Assert.AreEqual(34, args.GetArg("age")); - } - } - - public class Lump - { - } - - public class LumpProvider : ExplicitArgumentTester.IProvider - { - private readonly Lump _lump; - - public LumpProvider(Lump lump) - { - _lump = lump; - } - - - public Lump Lump - { - get { return _lump; } - } - } - - - public class Trade - { - } - - public class TradeView : IView - { - private readonly Trade _trade; - - public TradeView(Trade trade) - { - _trade = trade; - } - - public Trade Trade - { - get { return _trade; } - } - } - - public class SecuredTradeView : TradeView - { - public SecuredTradeView(Trade trade) : base(trade) - { - } - } - - public class Node - { - } - - public interface IView - { - } - - public class View : IView - { - } - - public class Command - { - private readonly Node _node; - private readonly Trade _trade; - private readonly IView _view; - - public Command(Trade trade, Node node, IView view) - { - _trade = trade; - _node = node; - _view = view; - } - - public Trade Trade - { - get { return _trade; } - } - - public Node Node - { - get { return _node; } - } - - public IView View - { - get { return _view; } - } - } - - public class TradeNode : Node - { - private readonly Trade _trade; - - public TradeNode(Trade trade) - { - _trade = trade; - } - - public Trade Trade - { - get { return _trade; } - } - } -} \ No newline at end of file Copied: trunk/Source/StructureMap.Testing/Graph/TestExplicitArguments.cs (from rev 180, trunk/Source/StructureMap.Testing/Graph/ExplicitArgumentTester.cs) =================================================================== --- trunk/Source/StructureMap.Testing/Graph/TestExplicitArguments.cs (rev 0) +++ trunk/Source/StructureMap.Testing/Graph/TestExplicitArguments.cs 2008-10-10 21:11:00 UTC (rev 181) @@ -0,0 +1,437 @@ +using System.Collections; +using System.Collections.Generic; +using NUnit.Framework; +using StructureMap.Pipeline; +using StructureMap.Testing.Pipeline; + +namespace StructureMap.Testing.Graph +{ + [TestFixture] + public class TestExplicitArguments + { + #region Setup/Teardown + + [SetUp] + public void SetUp() + { + ObjectFactory.Initialize(x => { x.UseDefaultStructureMapConfigFile = false; }); + } + + #endregion + + public interface IExplicitTarget + { + } + + public class RedTarget : IExplicitTarget + { + } + + public class GreenTarget : IExplicitTarget + { + } + + public class ExplicitTarget : IExplicitTarget + { + private readonly string _name; + private readonly IProvider _provider; + + public ExplicitTarget(string name, IProvider provider) + { + _name = name; + _provider = provider; + } + + + public string Name + { + get { return _name; } + } + + public IProvider Provider + { + get { return _provider; } + } + } + + public interface IProvider + { + } + + public class RedProvider : IProvider + { + } + + public class BlueProvider : IProvider + { + } + + [Test] + public void Example() + { + IContainer container = new Container(); + var theTrade = new Trade(); + + var view = container.With(theTrade).GetInstance<TradeView>(); + + view.Trade.ShouldBeTheSameAs(theTrade); + } + + [Test] + public void Explicit_services_are_used_throughout_the_object_graph() + { + var theTrade = new Trade(); + + IContainer container = new Container(r => + { + r.ForRequestedType<IView>().TheDefaultIsConcreteType<TradeView>(); + r.ForRequestedType<Node>().TheDefaultIsConcreteType<TradeNode>(); + }); + + var command = container.With(theTrade).GetInstance<Command>(); + + command.Trade.ShouldBeTheSameAs(theTrade); + command.Node.IsType<TradeNode>().Trade.ShouldBeTheSameAs(theTrade); + command.View.IsType<TradeView>().Trade.ShouldBeTheSameAs(theTrade); + } + + [Test] + public void ExplicitArguments_can_return_child_by_name() + { + var args = new ExplicitArguments(); + var theNode = new Node(); + args.SetArg("node", theNode); + + IConfiguredInstance instance = new ExplicitInstance(typeof (Command), args, null); + + Assert.AreSame(theNode, instance.GetChild("node", typeof (Node), new StubBuildSession())); + } + + [Test] + public void Fill_in_argument_by_name() + { + var container = new Container(); + container.SetDefault<IView, View>(); + + var theNode = new Node(); + var theTrade = new Trade(); + + var command = container + .With("node").EqualTo(theNode) + .With(theTrade) + .GetInstance<Command>(); + + Assert.IsInstanceOfType(typeof (View), command.View); + Assert.AreSame(theNode, command.Node); + Assert.AreSame(theTrade, command.Trade); + } + + [Test] + public void NowDoItWithObjectFactoryItself() + { + ObjectFactory.Initialize(x => + { + x.ForConcreteType<ExplicitTarget>().Configure + .CtorDependency<IProvider>().Is<RedProvider>() + .WithCtorArg("name").EqualTo("Jeremy"); + }); + + // Get the ExplicitTarget without setting an explicit arg for IProvider + var firstTarget = ObjectFactory.GetInstance<ExplicitTarget>(); + Assert.IsInstanceOfType(typeof (RedProvider), firstTarget.Provider); + + // Now, set the explicit arg for IProvider + var theBlueProvider = new BlueProvider(); + var secondTarget = ObjectFactory.With<IProvider>(theBlueProvider).GetInstance<ExplicitTarget>(); + Assert.AreSame(theBlueProvider, secondTarget.Provider); + } + + [Test] + public void NowDoItWithObjectFactoryItself_with_new_API() + { + ObjectFactory.Initialize(x => + { + x.ForRequestedType<ExplicitTarget>().TheDefault.Is.OfConcreteType<ExplicitTarget>() + .CtorDependency<IProvider>().Is(child => child.OfConcreteType<RedProvider>()) + .WithCtorArg("name").EqualTo("Jeremy"); + }); + + // Get the ExplicitTarget without setting an explicit arg for IProvider + ObjectFactory.GetInstance<ExplicitTarget>().Provider.IsType<RedProvider>(); + + // Now, set the explicit arg for IProvider + var theBlueProvider = new BlueProvider(); + ObjectFactory.With<IProvider>(theBlueProvider).GetInstance<ExplicitTarget>() + .Provider.ShouldBeTheSameAs(theBlueProvider); + } + + [Test] + public void OverrideAPrimitiveWithObjectFactory() + { + ObjectFactory.Initialize(x => + { + x.ForConcreteType<ExplicitTarget>().Configure + .CtorDependency<IProvider>().Is<RedProvider>() + .WithCtorArg("name").EqualTo("Jeremy"); + }); + + // Get the ExplicitTarget without setting an explicit arg for IProvider + var firstTarget = ObjectFactory.GetInstance<ExplicitTarget>(); + Assert.AreEqual("Jeremy", firstTarget.Name); + + // Now, set the explicit arg for IProvider + var secondTarget = ObjectFactory.With("name").EqualTo("Julia").GetInstance<ExplicitTarget>(); + Assert.AreEqual("Julia", secondTarget.Name); + } + + [Test] + public void pass_explicit_service_into_all_instances() + { + // The Container is constructed with 2 instances + // of TradeView + var container = new Container(r => + { + r.ForRequestedType<TradeView>() + .TheDefaultIsConcreteType<TradeView>() + .AddConcreteType<SecuredTradeView>(); + }); + + var theTrade = new Trade(); + + IList<TradeView> views = container.With(theTrade).GetAllInstances<TradeView>(); + + views[0].Trade.ShouldBeTheSameAs(theTrade); + views[1].Trade.ShouldBeTheSameAs(theTrade); + } + + [Test] + public void pass_explicit_service_into_all_instances_and_retrieve_without_generics() + { + // The Container is constructed with 2 instances + // of TradeView + var container = new Container(r => + { + r.ForRequestedType<TradeView>() + .TheDefaultIsConcreteType<TradeView>() + .AddConcreteType<SecuredTradeView>(); + }); + + var theTrade = new Trade(); + + IList views = container.With(theTrade).GetAllInstances(typeof(TradeView)); + + ((TradeView)views[0]).Trade.ShouldBeTheSameAs(theTrade); + ((TradeView)views[1]).Trade.ShouldBeTheSameAs(theTrade); + } + + + [Test] + public void Pass_in_arguments_as_dictionary() + { + var manager = new Container(); + manager.SetDefault<IView, View>(); + + var theNode = new Node(); + var theTrade = new Trade(); + + var args = new ExplicitArguments(); + args.Set(theNode); + args.SetArg("trade", theTrade); + + var command = manager.GetInstance<Command>(args); + + Assert.IsInstanceOfType(typeof (View), command.View); + Assert.AreSame(theNode, command.Node); + Assert.AreSame(theTrade, command.Trade); + } + + + [Test] + public void PassAnArgumentIntoExplicitArgumentsForARequestedInterface() + { + IContainer manager = + new Container( + registry => registry.ForRequestedType<IProvider>().TheDefaultIsConcreteType<LumpProvider>()); + + var args = new ExplicitArguments(); + var theLump = new Lump(); + args.Set(theLump); + + var instance = (LumpProvider) manager.GetInstance<IProvider>(args); + Assert.AreSame(theLump, instance.Lump); + } + + [Test] + public void PassAnArgumentIntoExplicitArgumentsForARequestedInterfaceUsingObjectFactory() + { + ObjectFactory.Initialize(x => { x.ForRequestedType<IProvider>().TheDefaultIsConcreteType<LumpProvider>(); }); + + + var theLump = new Lump(); + + var provider = (LumpProvider) ObjectFactory.With(theLump).GetInstance<IProvider>(); + Assert.AreSame(theLump, provider.Lump); + } + + [Test] + public void PassAnArgumentIntoExplicitArgumentsThatMightNotAlreadyBeRegistered() + { + var theLump = new Lump(); + var provider = ObjectFactory.With(theLump).GetInstance<LumpProvider>(); + Assert.AreSame(theLump, provider.Lump); + } + + [Test] + public void PassExplicitArgsIntoInstanceManager() + { + var container = new Container(r => + { + r.ForConcreteType<ExplicitTarget>().Configure + .CtorDependency<IProvider>().Is<RedProvider>() + .WithCtorArg("name").EqualTo("Jeremy"); + }); + + var args = new ExplicitArguments(); + + // Get the ExplicitTarget without setting an explicit arg for IProvider + var firstTarget = container.GetInstance<ExplicitTarget>(args); + Assert.IsInstanceOfType(typeof (RedProvider), firstTarget.Provider); + + // Now, set the explicit arg for IProvider + args.Set<IProvider>(new BlueProvider()); + var secondTarget = container.GetInstance<ExplicitTarget>(args); + Assert.IsInstanceOfType(typeof (BlueProvider), secondTarget.Provider); + } + + [Test] + public void RegisterAndFindServicesOnTheExplicitArgument() + { + var args = new ExplicitArguments(); + Assert.IsNull(args.Get<IProvider>()); + + var red = new RedProvider(); + args.Set<IProvider>(red); + + Assert.AreSame(red, args.Get<IProvider>()); + + args.Set<IExplicitTarget>(new RedTarget()); + Assert.IsInstanceOfType(typeof (RedTarget), args.Get<IExplicitTarget>()); + } + + [Test] + public void RegisterAndRetrieveArgs() + { + var args = new ExplicitArguments(); + Assert.IsNull(args.GetArg("name")); + + args.SetArg("name", "Jeremy"); + Assert.AreEqual("Jeremy", args.GetArg("name")); + + args.SetArg("age", 34); + Assert.AreEqual(34, args.GetArg("age")); + } + } + + public class Lump + { + } + + public class LumpProvider : TestExplicitArguments.IProvider + { + private readonly Lump _lump; + + public LumpProvider(Lump lump) + { + _lump = lump; + } + + + public Lump Lump + { + get { return _lump; } + } + } + + + public class Trade + { + } + + public class TradeView : IView + { + private readonly Trade _trade; + + public TradeView(Trade trade) + { + _trade = trade; + } + + public Trade Trade + { + get { return _trade; } + } + } + + public class SecuredTradeView : TradeView + { + public SecuredTradeView(Trade trade) : base(trade) + { + } + } + + public class Node + { + } + + public interface IView + { + } + + public class View : IView + { + } + + public class Command + { + private readonly Node _node; + private readonly Trade _trade; + private readonly IView _view; + + public Command(Trade trade, Node node, IView view) + { + _trade = trade; + _node = node; + _view = view; + } + + public Trade Trade + { + get { return _trade; } + } + + public Node Node + { + get { return _node; } + } + + public IView View + { + get { return _view; } + } + } + + public class TradeNode : Node + { + private readonly Trade _trade; + + public TradeNode(Trade trade) + { + _trade = trade; + } + + public Trade Trade + { + get { return _trade; } + } + } +} \ No newline at end of file Property changes on: trunk/Source/StructureMap.Testing/Graph/TestExplicitArguments.cs ___________________________________________________________________ Added: svn:mergeinfo + Modified: trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj =================================================================== --- trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj 2008-10-08 20:38:53 UTC (rev 180) +++ trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj 2008-10-10 21:11:00 UTC (rev 181) @@ -224,7 +224,7 @@ <Compile Include="Graph\ExceptionHandling\StructureMapExceptionTester.cs"> <SubType>Code</SubType> </Compile> - <Compile Include="Graph\ExplicitArgumentTester.cs" /> + <Compile Include="Graph\TestExplicitArguments.cs" /> <Compile Include="Graph\FillDependenciesTester.cs"> <SubType>Code</SubType> </Compile> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fli...@us...> - 2008-10-08 20:38:59
|
Revision: 180 http://structuremap.svn.sourceforge.net/structuremap/?rev=180&view=rev Author: flimflan Date: 2008-10-08 20:38:53 +0000 (Wed, 08 Oct 2008) Log Message: ----------- PartialMockTheClassUnderTest now puts the class under test in replay mode when using MockMode.AAA Modified Paths: -------------- trunk/Source/StructureMap.AutoMocking/RhinoAutoMocker.cs trunk/Source/StructureMap.AutoMocking/RhinoMocksServiceLocator.cs trunk/Source/StructureMap.Testing/AutoMocking/RhinoAutoMockerTester.cs Modified: trunk/Source/StructureMap.AutoMocking/RhinoAutoMocker.cs =================================================================== --- trunk/Source/StructureMap.AutoMocking/RhinoAutoMocker.cs 2008-10-08 20:12:24 UTC (rev 179) +++ trunk/Source/StructureMap.AutoMocking/RhinoAutoMocker.cs 2008-10-08 20:38:53 UTC (rev 180) @@ -23,25 +23,26 @@ private readonly AutoMockedContainer _container; private TARGETCLASS _classUnderTest; private readonly RhinoMocksServiceLocator _serviceLocator; + private readonly Func<object, object> _mockDecorator; public RhinoAutoMocker() : this(MockMode.RecordAndReplay) {} public RhinoAutoMocker(MockMode mockMode) { - var mockCreationStrategy = getMockCreationStrategy(mockMode); - _serviceLocator = new RhinoMocksServiceLocator(this, mockCreationStrategy); + _mockDecorator = getMockDecorator(mockMode); + _serviceLocator = new RhinoMocksServiceLocator(this, _mockDecorator); _container = new AutoMockedContainer(_serviceLocator); } - private static Func<MockRepository, Type, object> getMockCreationStrategy(MockMode mockMode) + private static Func<object, object> getMockDecorator(MockMode mockMode) { switch (mockMode) { case MockMode.RecordAndReplay: - return MockCreationStrategy.RecordMode; + return MockDecorator.Nullo; case MockMode.AAA: - return MockCreationStrategy.ReplayMode; + return MockDecorator.PutInReplayMode; default: throw new InvalidOperationException("Unsupported MockMode " + mockMode); } @@ -88,7 +89,7 @@ /// </summary> public void PartialMockTheClassUnderTest() { - _classUnderTest = PartialMock<TARGETCLASS>(getConstructorArgs()); + _classUnderTest = (TARGETCLASS)_mockDecorator(PartialMock<TARGETCLASS>(getConstructorArgs())); } private object[] getConstructorArgs() Modified: trunk/Source/StructureMap.AutoMocking/RhinoMocksServiceLocator.cs =================================================================== --- trunk/Source/StructureMap.AutoMocking/RhinoMocksServiceLocator.cs 2008-10-08 20:12:24 UTC (rev 179) +++ trunk/Source/StructureMap.AutoMocking/RhinoMocksServiceLocator.cs 2008-10-08 20:38:53 UTC (rev 180) @@ -6,15 +6,15 @@ public class RhinoMocksServiceLocator : ServiceLocator { private readonly MockRepository _mocks; - private readonly Func<MockRepository, Type, object> mockCreationStrategy; + private readonly Func<object, object> _mockDecorator; - public RhinoMocksServiceLocator(MockRepository mocks, Func<MockRepository, Type, object> mockCreationStrategy) + public RhinoMocksServiceLocator(MockRepository mocks, Func<object, object> mockDecorator) { _mocks = mocks; - this.mockCreationStrategy = mockCreationStrategy; + _mockDecorator = mockDecorator; } - public RhinoMocksServiceLocator(MockRepository mocks) : this(mocks, MockCreationStrategy.RecordMode) + public RhinoMocksServiceLocator(MockRepository mocks) : this(mocks, MockDecorator.Nullo) { } @@ -26,28 +26,27 @@ public T Service<T>() { - return (T)mockCreationStrategy(_mocks, typeof (T)); + return (T) Service(typeof (T)); } public object Service(Type serviceType) { - return mockCreationStrategy(_mocks, serviceType); + return _mockDecorator(_mocks.DynamicMock(serviceType)); } #endregion } - public static class MockCreationStrategy + public static class MockDecorator { - public static object RecordMode(MockRepository repository, Type type) + public static object Nullo(object mock) { - return repository.DynamicMock(type); + return mock; } - public static object ReplayMode(MockRepository repository, Type type) + public static object PutInReplayMode(object mock) { - var mock = repository.DynamicMock(type); - repository.Replay(mock); + mock.Replay(); return mock; } } Modified: trunk/Source/StructureMap.Testing/AutoMocking/RhinoAutoMockerTester.cs =================================================================== --- trunk/Source/StructureMap.Testing/AutoMocking/RhinoAutoMockerTester.cs 2008-10-08 20:12:24 UTC (rev 179) +++ trunk/Source/StructureMap.Testing/AutoMocking/RhinoAutoMockerTester.cs 2008-10-08 20:38:53 UTC (rev 180) @@ -405,5 +405,15 @@ autoMocker.IsInReplayMode(autoMocker.Get<IMockedService>()).ShouldBeTrue(); } + + [Test] + public void PartialMockClassUnderTestPutsTheClassUnderTestInReplayModeWhenUsingAAA() + { + var autoMocker = new RhinoAutoMocker<ConcreteClass>(MockMode.AAA); + autoMocker.PartialMockTheClassUnderTest(); + + autoMocker.IsInReplayMode(autoMocker.ClassUnderTest).ShouldBeTrue(); + } + } } \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fli...@us...> - 2008-10-08 20:12:29
|
Revision: 179 http://structuremap.svn.sourceforge.net/structuremap/?rev=179&view=rev Author: flimflan Date: 2008-10-08 20:12:24 +0000 (Wed, 08 Oct 2008) Log Message: ----------- Fixed AAA support for PartialMockTheClassUnderTest, AddAdditionalMockFor, and CreateMockArrayFor Modified Paths: -------------- trunk/Source/StructureMap.AutoMocking/RhinoAutoMocker.cs trunk/Source/StructureMap.Testing/AutoMocking/RhinoAutoMockerTester.cs Modified: trunk/Source/StructureMap.AutoMocking/RhinoAutoMocker.cs =================================================================== --- trunk/Source/StructureMap.AutoMocking/RhinoAutoMocker.cs 2008-10-08 19:29:40 UTC (rev 178) +++ trunk/Source/StructureMap.AutoMocking/RhinoAutoMocker.cs 2008-10-08 20:12:24 UTC (rev 179) @@ -22,14 +22,15 @@ { private readonly AutoMockedContainer _container; private TARGETCLASS _classUnderTest; + private readonly RhinoMocksServiceLocator _serviceLocator; public RhinoAutoMocker() : this(MockMode.RecordAndReplay) {} public RhinoAutoMocker(MockMode mockMode) { var mockCreationStrategy = getMockCreationStrategy(mockMode); - var serviceLocator = new RhinoMocksServiceLocator(this, mockCreationStrategy); - _container = new AutoMockedContainer(serviceLocator); + _serviceLocator = new RhinoMocksServiceLocator(this, mockCreationStrategy); + _container = new AutoMockedContainer(_serviceLocator); } @@ -159,7 +160,7 @@ /// <returns></returns> public T AddAdditionalMockFor<T>() where T : class { - var mock = DynamicMock<T>(); + var mock = _serviceLocator.Service<T>(); _container.Configure(r => r.InstanceOf<T>().Is.Object(mock)); return mock; @@ -190,7 +191,7 @@ for (int i = 0; i < returnValue.Length; i++) { - returnValue[i] = DynamicMock<T>(); + returnValue[i] = _serviceLocator.Service<T>(); } InjectArray(returnValue); Modified: trunk/Source/StructureMap.Testing/AutoMocking/RhinoAutoMockerTester.cs =================================================================== --- trunk/Source/StructureMap.Testing/AutoMocking/RhinoAutoMockerTester.cs 2008-10-08 19:29:40 UTC (rev 178) +++ trunk/Source/StructureMap.Testing/AutoMocking/RhinoAutoMockerTester.cs 2008-10-08 20:12:24 UTC (rev 179) @@ -338,9 +338,72 @@ var autoMocker = new RhinoAutoMocker<ConcreteClass>(MockMode.AAA); autoMocker.ClassUnderTest.CallService(); + autoMocker.IsInReplayMode(autoMocker.Get<IMockedService>()).ShouldBeTrue(); autoMocker.Get<IMockedService>().AssertWasCalled(s => s.Go()); } + public interface IAnotherService + { + + } + + [Test] + public void AddAdditionalMockForCreatesMocksInRecordModeWhenUsingRecordReplay() + { + var autoMocker = new RhinoAutoMocker<ConcreteClass>(MockMode.RecordAndReplay); + autoMocker.AddAdditionalMockFor<IAnotherService>(); + + autoMocker.IsInReplayMode(autoMocker.Get<IAnotherService>()).ShouldBeFalse(); + } + + [Test] + public void AddAdditionalMockForCreatesMocksInReplayModeWhenUsingAAA() + { + var autoMocker = new RhinoAutoMocker<ConcreteClass>(MockMode.AAA); + autoMocker.AddAdditionalMockFor<IAnotherService>(); + + autoMocker.IsInReplayMode(autoMocker.Get<IAnotherService>()).ShouldBeTrue(); + } + + [Test] + public void CreateMockArrayForCreatesMocksInRecordModeWhenUsingReplayRecord() + { + var autoMocker = new RhinoAutoMocker<ConcreteClass>(MockMode.RecordAndReplay); + var mockArray = autoMocker.CreateMockArrayFor<IAnotherService>(3); + foreach (var service in mockArray) + { + autoMocker.IsInReplayMode(service).ShouldBeFalse(); + } + } + + [Test] + public void CreateMockArrayForCreatesMocksInReplayModeWhenUsingAAA() + { + var autoMocker = new RhinoAutoMocker<ConcreteClass>(MockMode.AAA); + var mockArray = autoMocker.CreateMockArrayFor<IAnotherService>(3); + foreach (var service in mockArray) + { + autoMocker.IsInReplayMode(service).ShouldBeTrue(); + } + } + + [Test] + public void PartialMockClassUnderTestCreatesMocksInRecordModeWhenUsingRecordReplay() + { + var autoMocker = new RhinoAutoMocker<ConcreteClass>(MockMode.RecordAndReplay); + autoMocker.PartialMockTheClassUnderTest(); + + autoMocker.IsInReplayMode(autoMocker.Get<IMockedService>()).ShouldBeFalse(); + } + + [Test] + public void PartialMockClassUnderTestCreatesMocksInReplayModeWhenUsingAAA() + { + var autoMocker = new RhinoAutoMocker<ConcreteClass>(MockMode.AAA); + autoMocker.PartialMockTheClassUnderTest(); + + autoMocker.IsInReplayMode(autoMocker.Get<IMockedService>()).ShouldBeTrue(); + } } } \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jer...@us...> - 2008-10-08 19:29:46
|
Revision: 178 http://structuremap.svn.sourceforge.net/structuremap/?rev=178&view=rev Author: jeremydmiller Date: 2008-10-08 19:29:40 +0000 (Wed, 08 Oct 2008) Log Message: ----------- little fix for Kevin Modified Paths: -------------- trunk/Source/StructureMap/Configuration/ConfigurationParser.cs trunk/Source/StructureMap/Configuration/ConfigurationParserBuilder.cs trunk/Source/StructureMap/Configuration/XmlExtensions.cs trunk/Source/StructureMap/Diagnostics/ValidationBuildSession.cs trunk/Source/StructureMap/Interceptors/Interceptors.cs trunk/Source/StructureMap.AutoMocking/RhinoAutoMocker.cs trunk/Source/StructureMap.Testing/AutoMocking/RhinoAutoMockerTester.cs Modified: trunk/Source/StructureMap/Configuration/ConfigurationParser.cs =================================================================== --- trunk/Source/StructureMap/Configuration/ConfigurationParser.cs 2008-10-08 18:14:10 UTC (rev 177) +++ trunk/Source/StructureMap/Configuration/ConfigurationParser.cs 2008-10-08 19:29:40 UTC (rev 178) @@ -71,6 +71,9 @@ public void ForEachFile(GraphLog log, Action<string> action) { string includePath = getIncludePath(); + + // Find the text in every child node of _structureMapNode and + // perform an action with that text _structureMapNode.ForTextInChild("Include/@File").Do(fileName => { string includedFile = Path.Combine(includePath, fileName); Modified: trunk/Source/StructureMap/Configuration/ConfigurationParserBuilder.cs =================================================================== --- trunk/Source/StructureMap/Configuration/ConfigurationParserBuilder.cs 2008-10-08 18:14:10 UTC (rev 177) +++ trunk/Source/StructureMap/Configuration/ConfigurationParserBuilder.cs 2008-10-08 19:29:40 UTC (rev 178) @@ -85,12 +85,12 @@ { foreach (ConfigurationParser parser in list.ToArray()) { - parser.ForEachFile(_log, - filename => _log.Try(() => - { - ConfigurationParser childParser = ConfigurationParser.FromFile(filename); - list.Add(childParser); - }).AndReportErrorAs(150, filename)); + parser.ForEachFile(_log, filename => _log.Try(() => + { + ConfigurationParser childParser = ConfigurationParser.FromFile(filename); + list.Add(childParser); + }) + .AndReportErrorAs(150, filename)); } } Modified: trunk/Source/StructureMap/Configuration/XmlExtensions.cs =================================================================== --- trunk/Source/StructureMap/Configuration/XmlExtensions.cs 2008-10-08 18:14:10 UTC (rev 177) +++ trunk/Source/StructureMap/Configuration/XmlExtensions.cs 2008-10-08 19:29:40 UTC (rev 178) @@ -16,6 +16,26 @@ return new XmlTextExpression(node, xpath); } + public class XmlTextExpression + { + private readonly XmlNodeList _list; + + internal XmlTextExpression(XmlNode parent, string attributePath) + { + _list = parent.SelectNodes(attributePath); + } + + public void Do(Action<string> action) + { + if (_list == null) return; + + foreach (XmlNode node in _list) + { + action(node.InnerText); + } + } + } + public static XmlNodeExpression ForEachChild(this XmlNode node, string xpath) { return new XmlNodeExpression(node, xpath); @@ -93,26 +113,8 @@ #region Nested type: XmlTextExpression - public class XmlTextExpression - { - private readonly XmlNodeList _list; - internal XmlTextExpression(XmlNode parent, string attributePath) - { - _list = parent.SelectNodes(attributePath); - } - public void Do(Action<string> action) - { - if (_list == null) return; - - foreach (XmlNode node in _list) - { - action(node.InnerText); - } - } - } - #endregion } } \ No newline at end of file Modified: trunk/Source/StructureMap/Diagnostics/ValidationBuildSession.cs =================================================================== --- trunk/Source/StructureMap/Diagnostics/ValidationBuildSession.cs 2008-10-08 18:14:10 UTC (rev 177) +++ trunk/Source/StructureMap/Diagnostics/ValidationBuildSession.cs 2008-10-08 19:29:40 UTC (rev 178) @@ -134,6 +134,7 @@ writer.WriteLine(); + writer.WriteLine("StructureMap Failures: {0} Build/Configuration Failures and {1} Validation Errors", _errors.BuildErrors.Length, _validationErrors.Count); Modified: trunk/Source/StructureMap/Interceptors/Interceptors.cs =================================================================== --- trunk/Source/StructureMap/Interceptors/Interceptors.cs 2008-10-08 18:14:10 UTC (rev 177) +++ trunk/Source/StructureMap/Interceptors/Interceptors.cs 2008-10-08 19:29:40 UTC (rev 178) @@ -1,4 +1,4 @@ namespace StructureMap.Interceptors { - public delegate T EnrichmentHandler<T>(T target); + public delegate object EnrichmentHandler<T>(T target); } \ No newline at end of file Modified: trunk/Source/StructureMap.AutoMocking/RhinoAutoMocker.cs =================================================================== --- trunk/Source/StructureMap.AutoMocking/RhinoAutoMocker.cs 2008-10-08 18:14:10 UTC (rev 177) +++ trunk/Source/StructureMap.AutoMocking/RhinoAutoMocker.cs 2008-10-08 19:29:40 UTC (rev 178) @@ -11,7 +11,7 @@ public delegate void VoidMethod(); - public enum MockMode { Record, Replay } + public enum MockMode { RecordAndReplay, AAA } // Note that it subclasses the RhinoMocks.MockRepository class /// <summary> @@ -23,7 +23,7 @@ private readonly AutoMockedContainer _container; private TARGETCLASS _classUnderTest; - public RhinoAutoMocker() : this(MockMode.Record) {} + public RhinoAutoMocker() : this(MockMode.RecordAndReplay) {} public RhinoAutoMocker(MockMode mockMode) { @@ -37,9 +37,9 @@ { switch (mockMode) { - case MockMode.Record: + case MockMode.RecordAndReplay: return MockCreationStrategy.RecordMode; - case MockMode.Replay: + case MockMode.AAA: return MockCreationStrategy.ReplayMode; default: throw new InvalidOperationException("Unsupported MockMode " + mockMode); Modified: trunk/Source/StructureMap.Testing/AutoMocking/RhinoAutoMockerTester.cs =================================================================== --- trunk/Source/StructureMap.Testing/AutoMocking/RhinoAutoMockerTester.cs 2008-10-08 18:14:10 UTC (rev 177) +++ trunk/Source/StructureMap.Testing/AutoMocking/RhinoAutoMockerTester.cs 2008-10-08 19:29:40 UTC (rev 178) @@ -335,7 +335,7 @@ [Test] public void TheAutoMockerOptionallyPushesInMocksInReplayModeToAllowForAAAsyntax() { - var autoMocker = new RhinoAutoMocker<ConcreteClass>(MockMode.Replay); + var autoMocker = new RhinoAutoMocker<ConcreteClass>(MockMode.AAA); autoMocker.ClassUnderTest.CallService(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fli...@us...> - 2008-10-08 18:14:19
|
Revision: 177 http://structuremap.svn.sourceforge.net/structuremap/?rev=177&view=rev Author: flimflan Date: 2008-10-08 18:14:10 +0000 (Wed, 08 Oct 2008) Log Message: ----------- Upgraded Rhino.Mocks.dll for RhinoAutoMocker to Rhino 3.5 RTM Modified Paths: -------------- trunk/Source/StructureMap.AutoMocking/RhinoAutoMocker.cs trunk/Source/StructureMap.AutoMocking/StructureMap.AutoMocking.csproj trunk/bin/Rhino.Mocks.dll Modified: trunk/Source/StructureMap.AutoMocking/RhinoAutoMocker.cs =================================================================== --- trunk/Source/StructureMap.AutoMocking/RhinoAutoMocker.cs 2008-10-06 14:52:15 UTC (rev 176) +++ trunk/Source/StructureMap.AutoMocking/RhinoAutoMocker.cs 2008-10-08 18:14:10 UTC (rev 177) @@ -157,7 +157,7 @@ /// </summary> /// <typeparam name="T"></typeparam> /// <returns></returns> - public T AddAdditionalMockFor<T>() + public T AddAdditionalMockFor<T>() where T : class { var mock = DynamicMock<T>(); _container.Configure(r => r.InstanceOf<T>().Is.Object(mock)); @@ -184,7 +184,7 @@ /// <typeparam name="T"></typeparam> /// <param name="count"></param> /// <returns></returns> - public T[] CreateMockArrayFor<T>(int count) + public T[] CreateMockArrayFor<T>(int count) where T : class { var returnValue = new T[count]; Modified: trunk/Source/StructureMap.AutoMocking/StructureMap.AutoMocking.csproj =================================================================== --- trunk/Source/StructureMap.AutoMocking/StructureMap.AutoMocking.csproj 2008-10-06 14:52:15 UTC (rev 176) +++ trunk/Source/StructureMap.AutoMocking/StructureMap.AutoMocking.csproj 2008-10-08 18:14:10 UTC (rev 177) @@ -51,7 +51,7 @@ <WarningLevel>4</WarningLevel> </PropertyGroup> <ItemGroup> - <Reference Include="Rhino.Mocks, Version=2.9.1.10183, Culture=neutral, PublicKeyToken=0b3305902db7183f, processorArchitecture=MSIL"> + <Reference Include="Rhino.Mocks, Version=3.5.0.1337, Culture=neutral, PublicKeyToken=0b3305902db7183f, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> <HintPath>..\..\bin\Rhino.Mocks.dll</HintPath> </Reference> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jer...@us...> - 2008-10-06 16:22:15
|
Revision: 176 http://structuremap.svn.sourceforge.net/structuremap/?rev=176&view=rev Author: jeremydmiller Date: 2008-10-06 14:52:15 +0000 (Mon, 06 Oct 2008) Log Message: ----------- fixing a bug with using arrays as a constraint in a generic type Modified Paths: -------------- trunk/Source/HTML/FluentInterfaceAPI.htm trunk/Source/StructureMap/Configuration/DSL/Expressions/InstanceExpression.cs trunk/Source/StructureMap/Emitting/InstanceBuilderAssembly.cs trunk/Source/StructureMap/Graph/GenericsPluginGraph.cs trunk/Source/StructureMap/PipelineGraph.cs trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj Added Paths: ----------- trunk/Source/StructureMap.Testing/Examples/ trunk/Source/StructureMap.Testing/Examples/RegisteringWithTheAPI.cs Modified: trunk/Source/HTML/FluentInterfaceAPI.htm =================================================================== --- trunk/Source/HTML/FluentInterfaceAPI.htm 2008-10-05 04:04:34 UTC (rev 175) +++ trunk/Source/HTML/FluentInterfaceAPI.htm 2008-10-06 14:52:15 UTC (rev 176) @@ -1,10 +1,13 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> - <title></title> + <title>Configuring StructureMap with the Programmatic API</title> </head> <body> - <h4>Adding an Instance by Type</h4> + <h4>Configuring StructureMap with the Programmatic API</h4> + <p> + </p> + </body> </html> \ No newline at end of file Modified: trunk/Source/StructureMap/Configuration/DSL/Expressions/InstanceExpression.cs =================================================================== --- trunk/Source/StructureMap/Configuration/DSL/Expressions/InstanceExpression.cs 2008-10-05 04:04:34 UTC (rev 175) +++ trunk/Source/StructureMap/Configuration/DSL/Expressions/InstanceExpression.cs 2008-10-06 14:52:15 UTC (rev 176) @@ -5,8 +5,22 @@ { public interface IsExpression<T> { + /// <summary> + /// Gives you full access to all the different ways to specify an "Instance" + /// </summary> InstanceExpression<T> Is { get; } + + /// <summary> + /// Shortcut to specify a prebuilt Instance + /// </summary> + /// <param name="instance"></param> void IsThis(Instance instance); + + /// <summary> + /// Shortcut to directly inject an object + /// </summary> + /// <param name="obj"></param> + /// <returns></returns> LiteralInstance IsThis(T obj); } Modified: trunk/Source/StructureMap/Emitting/InstanceBuilderAssembly.cs =================================================================== --- trunk/Source/StructureMap/Emitting/InstanceBuilderAssembly.cs 2008-10-05 04:04:34 UTC (rev 175) +++ trunk/Source/StructureMap/Emitting/InstanceBuilderAssembly.cs 2008-10-06 14:52:15 UTC (rev 176) @@ -58,7 +58,7 @@ private static string escapeClassName(Type type) { string typeName = type.Namespace + type.Name; - string returnValue = typeName.Replace(".", string.Empty); + string returnValue = typeName.Replace(".", string.Empty).Replace("[]", "Array"); return returnValue.Replace("`", string.Empty); } Modified: trunk/Source/StructureMap/Graph/GenericsPluginGraph.cs =================================================================== --- trunk/Source/StructureMap/Graph/GenericsPluginGraph.cs 2008-10-05 04:04:34 UTC (rev 175) +++ trunk/Source/StructureMap/Graph/GenericsPluginGraph.cs 2008-10-06 14:52:15 UTC (rev 176) @@ -23,7 +23,7 @@ { get { - foreach (PluginFamily family in _families) + foreach (PluginFamily family in _families.GetAll()) { yield return family.GetConfiguration(); } Modified: trunk/Source/StructureMap/PipelineGraph.cs =================================================================== --- trunk/Source/StructureMap/PipelineGraph.cs 2008-10-05 04:04:34 UTC (rev 175) +++ trunk/Source/StructureMap/PipelineGraph.cs 2008-10-06 14:52:15 UTC (rev 176) @@ -74,10 +74,11 @@ yield return configuration; } - foreach (var pair in _factories) + IInstanceFactory[] factories = new IInstanceFactory[_factories.Count]; + _factories.Values.CopyTo(factories, 0); + + foreach (var factory in factories) { - IInstanceFactory factory = pair.Value; - yield return new PluginTypeConfiguration { Default = _profileManager.GetDefault(factory.PluginType), Added: trunk/Source/StructureMap.Testing/Examples/RegisteringWithTheAPI.cs =================================================================== --- trunk/Source/StructureMap.Testing/Examples/RegisteringWithTheAPI.cs (rev 0) +++ trunk/Source/StructureMap.Testing/Examples/RegisteringWithTheAPI.cs 2008-10-06 14:52:15 UTC (rev 176) @@ -0,0 +1,58 @@ +using StructureMap.Configuration.DSL; + +namespace StructureMap.Testing.Examples +{ + public interface IRepository + { + } + + public class InMemoryRepository : IRepository + { + } + + public class DatabaseRepository : IRepository + { + public DatabaseRepository(string connectionString) + { + } + } + + // WeirdLegacyRepository is some sort of Singleton that we + // can't create directly with a constructor function + public class WeirdLegacyRepository : IRepository + { + private WeirdLegacyRepository() + { + } + + public static WeirdLegacyRepository Current { get; set; } + } + + + public class RepositoryRegistry : Registry + { + public RepositoryRegistry() + { + // First I'll specify the "default" Instance of IRepository + ForRequestedType<IRepository>().TheDefaultIsConcreteType<InMemoryRepository>(); + + // Now, I'll add three more Instances of IRepository + ForRequestedType<IRepository>().AddInstances(x => + { + // "NorthAmerica" is the concrete type DatabaseRepository with + // the connectionString pointed to the NorthAmerica database + x.OfConcreteType<DatabaseRepository>().WithName("NorthAmerica") + .WithCtorArg("connectionString").EqualTo("database=NorthAmerica"); + + // "Asia/Pacific" is the concrete type DatabaseRepository with + // the connectionString pointed to the AsiaPacific database + x.OfConcreteType<DatabaseRepository>().WithName("Asia/Pacific") + .WithCtorArg("connectionString").EqualTo("database=AsiaPacific"); + + // Lastly, the "Weird" instance is built by calling a specified + // Lambda (an anonymous delegate will work as well). + x.ConstructedBy(() => WeirdLegacyRepository.Current).WithName("Weird"); + }); + } + } +} \ No newline at end of file Modified: trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj =================================================================== --- trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj 2008-10-05 04:04:34 UTC (rev 175) +++ trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj 2008-10-06 14:52:15 UTC (rev 176) @@ -205,6 +205,7 @@ <Compile Include="Examples.cs"> <SubType>Form</SubType> </Compile> + <Compile Include="Examples\RegisteringWithTheAPI.cs" /> <Compile Include="Graph\ArrayConstructorTester.cs"> <SubType>Code</SubType> </Compile> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |