User: xtoff
Date: 2010/01/15 12:14 PM
Added:
/InversionOfControl/trunk/src/Castle.MicroKernel/ModelBuilder/Inspectors/
AdditionalInterfacesInspector.cs, MixinInspector.cs
/InversionOfControl/trunk/src/Castle.MicroKernel/Proxy/
ComponentReference.cs, IReference.cs, InstanceReference.cs
/InversionOfControl/trunk/src/Castle.Windsor.Tests/
AdditionalInterfaces.config, InterceptorsWithHookAndSelector.config,
Mixins.config, ProxyAllHook.cs, SelectAllSelector.cs
Modified:
/InversionOfControl/trunk/src/
InversionOfControl-vs2008.sln
/InversionOfControl/trunk/src/Castle.MicroKernel.Tests/Registration/
ComponentRegistrationTestCase.cs
/InversionOfControl/trunk/src/Castle.MicroKernel/
Castle.MicroKernel-vs2008.csproj
/InversionOfControl/trunk/src/Castle.MicroKernel/ModelBuilder/
DefaultComponentModelBuilder.cs
/InversionOfControl/trunk/src/Castle.MicroKernel/ModelBuilder/Inspectors/
InterceptorInspector.cs
/InversionOfControl/trunk/src/Castle.MicroKernel/Proxy/
ProxyOptions.cs
/InversionOfControl/trunk/src/Castle.MicroKernel/Registration/Interceptor/
InterceptorSelectorDescriptor.cs
/InversionOfControl/trunk/src/Castle.Windsor.Tests/
Castle.Windsor.Tests-vs2008.csproj, InterceptorsTestCase.cs
/InversionOfControl/trunk/src/Castle.Windsor.Tests/Components/
SimpleMixIn.cs
/InversionOfControl/trunk/src/Castle.Windsor/Installer/
DefaultComponentInstaller.cs
/InversionOfControl/trunk/src/Castle.Windsor/Proxy/
AbstractProxyFactory.cs, DefaultProxyFactory.cs
Log:
- added support for specifying interceptorsSelector, proxyHook and mixins from
config (see new tests for example). This also means some small impact breaking
changes:
- DefaultProxyFactory.CreateProxyGenerationOptionsFrom protected method
has changed signature - it now also takes IKernel and CreationContext, to be
used by IReferences to do resolve (see below)
- DefaultProxyFactory.CustomizeProxy protected virtual method has
changed signature, for the same reason as above
- ProxyOption's properties changed types: Selector, from
IInterceptorSelector to IReference<IInterceptorSelector>, Hook from IProxyHook
to IReference<IProxyHook>, MixIns from object[] to
IEnumerable<IReference<object>>, IReference abstraction allows to use
components resolved from the container, similar to InterceptorReferences (which
shall inherit from that interface in the future).
File Changes:
Directory: /InversionOfControl/trunk/src/Castle.MicroKernel/
============================================================
File [modified]: Castle.MicroKernel-vs2008.csproj
Delta lines: +3 -0
===================================================================
---
InversionOfControl/trunk/src/Castle.MicroKernel/ModelBuilder/DefaultComponentModelBuilder.cs
2010-01-15 16:53:40 UTC (rev 6690)
+++
InversionOfControl/trunk/src/Castle.MicroKernel/ModelBuilder/DefaultComponentModelBuilder.cs
2010-01-15 19:14:07 UTC (rev 6691)
@@ -17,6 +17,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
+
using Castle.Core;
using Castle.MicroKernel.ModelBuilder.Inspectors;
@@ -113,6 +114,8 @@
AddContributor(new
PropertiesDependenciesModelInspector());
AddContributor(new LifecycleModelInspector());
AddContributor(new InterceptorInspector());
+ AddContributor(new MixinInspector());
+ AddContributor(new AdditionalInterfacesInspector());
AddContributor(new ComponentActivatorInspector());
AddContributor(new ComponentProxyInspector());
Directory: /InversionOfControl/trunk/src/Castle.Windsor.Tests/
==============================================================
File [added]: AdditionalInterfaces.config
Delta lines: +6 -1
===================================================================
---
InversionOfControl/trunk/src/Castle.Windsor.Tests/Castle.Windsor.Tests-vs2008.csproj
2010-01-15 16:53:40 UTC (rev 6690)
+++
InversionOfControl/trunk/src/Castle.Windsor.Tests/Castle.Windsor.Tests-vs2008.csproj
2010-01-15 19:14:07 UTC (rev 6691)
@@ -293,7 +293,9 @@
<Compile
Include="Facilities\TypedFactory\TypedFactoryFacilityTake2TestCase.cs" />
<Compile Include="InterceptorSelectorTestCase.cs" />
<Compile Include="OpenGenericsTestCase.cs" />
+ <Compile Include="ProxyAllHook.cs" />
<Compile Include="RegisteringTwoServicesForSameType.cs" />
+ <Compile Include="SelectAllSelector.cs" />
<Compile Include="SubResolversShouldNotBeTrustedToBeCorrect.cs" />
<Compile Include="ModelInterceptorsSelectorTestCase.cs" />
<Compile Include="DependencyProblem.cs">
@@ -428,12 +430,16 @@
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
+ <EmbeddedResource Include="InterceptorsWithHookAndSelector.config" />
+ <EmbeddedResource Include="Mixins.config" />
+ <EmbeddedResource Include="AdditionalInterfaces.config" />
<None Include="DotNet2Config\chainOfRespnsability.config" />
<None Include="DotNet2Config\chainOfRespnsability_smart.config" />
<None Include="Facilities\EventWiring\App.config" />
<EmbeddedResource Include="InterceptorsMultiple.config" />
<EmbeddedResource Include="InterceptorsInvalid.config" />
<EmbeddedResource Include="Interceptors.config" />
+ <Content Include="Configuration2\config_with_forwarded_types.xml" />
<Content Include="RemotingTcpConfig2.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -449,7 +455,6 @@
<EmbeddedResource Include="Facilities\EventWiring\Config\startable.config"
/>
<EmbeddedResource Include="Configuration2\env_config.xml" />
<EmbeddedResource Include="Configuration2\eval_config.xml" />
- <Content Include="Configuration2\config_with_forwarded_types.xml" />
<Content Include="Configuration2\synchtest_config.xml" />
<EmbeddedResource Include="sample_config_with_spaces.xml" />
File [modified]: Castle.Windsor.Tests-vs2008.csproj
Delta lines: +1 -3
===================================================================
--- InversionOfControl/trunk/src/Castle.Windsor.Tests/Components/SimpleMixIn.cs
2010-01-15 16:53:40 UTC (rev 6690)
+++ InversionOfControl/trunk/src/Castle.Windsor.Tests/Components/SimpleMixIn.cs
2010-01-15 19:14:07 UTC (rev 6691)
@@ -14,14 +14,12 @@
namespace Castle.Windsor.Tests.Components
{
- using System;
-
/// <summary>
/// Summary description for ISimpleMixIn.
/// </summary>
public interface ISimpleMixIn
{
- void DoSomething();
+ void DoSomething();
}
File [modified]: InterceptorsTestCase.cs
Delta lines: +14 -0
===================================================================
---
InversionOfControl/trunk/src/Castle.Windsor.Tests/InterceptorsWithHookAndSelector.config
(rev 0)
+++
InversionOfControl/trunk/src/Castle.Windsor.Tests/InterceptorsWithHookAndSelector.config
2010-01-15 19:14:07 UTC (rev 6691)
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+ <components>
+ <component id="myInterceptor"
type="Castle.Windsor.Tests.ResultModifierInterceptor, Castle.Windsor.Tests"/>
+ <component id="testInterceptorSelector"
type="Castle.Windsor.Tests.SelectAllSelector, Castle.Windsor.Tests"/>
+ <component id="testProxyHook"
type="Castle.Windsor.Tests.ProxyAllHook, Castle.Windsor.Tests"/>
+ <component
+ id="ValidComponent"
+
type="Castle.Windsor.Tests.Components.CalculatorService, Castle.Windsor.Tests">
+ <interceptors selector="${testInterceptorSelector}"
hook="${testProxyHook}">
+ <interceptor>${myInterceptor}</interceptor>
+ </interceptors>
+ </component>
+ </components>
File [added]: InterceptorsWithHookAndSelector.config
Delta lines: +14 -0
===================================================================
--- InversionOfControl/trunk/src/Castle.Windsor.Tests/Mixins.config
(rev 0)
+++ InversionOfControl/trunk/src/Castle.Windsor.Tests/Mixins.config
2010-01-15 19:14:07 UTC (rev 6691)
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+ <components>
+ <component
+ id="myOtherService"
+ type="Castle.Windsor.Tests.Components.SimpleMixIn,
Castle.Windsor.Tests" />
+ <component
+ id="ValidComponent"
+
type="Castle.Windsor.Tests.Components.CalculatorService, Castle.Windsor.Tests">
+ <mixins>
+ <mixin>${myOtherService}</mixin>
+ </mixins>
+ </component>
+ </components>
File [added]: Mixins.config
Delta lines: +43 -0
===================================================================
--- InversionOfControl/trunk/src/Castle.Windsor.Tests/ProxyAllHook.cs
(rev 0)
+++ InversionOfControl/trunk/src/Castle.Windsor.Tests/ProxyAllHook.cs
2010-01-15 19:14:07 UTC (rev 6691)
@@ -0,0 +1,43 @@
+// Copyright 2004-2009 Castle Project - http://www.castleproject.org/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+namespace Castle.Windsor.Tests
+{
+ using System;
+ using System.Reflection;
+
+ using Castle.MicroKernel.Proxy;
+
+ public class ProxyAllHook : IProxyHook
+ {
+ public static int Instances;
+ public ProxyAllHook()
+ {
+ Instances++;
+ }
+
+ public bool ShouldInterceptMethod(Type type, MethodInfo
memberInfo)
+ {
+ return true;
+ }
+
+ public void NonVirtualMemberNotification(Type type, MemberInfo
memberInfo)
+ {
+ }
+
+ public void MethodsInspected()
+ {
+ }
+ }
+}
File [added]: ProxyAllHook.cs
Delta lines: +38 -0
===================================================================
--- InversionOfControl/trunk/src/Castle.Windsor.Tests/SelectAllSelector.cs
(rev 0)
+++ InversionOfControl/trunk/src/Castle.Windsor.Tests/SelectAllSelector.cs
2010-01-15 19:14:07 UTC (rev 6691)
@@ -0,0 +1,38 @@
+// Copyright 2004-2009 Castle Project - http://www.castleproject.org/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+namespace Castle.Windsor.Tests
+{
+ using System;
+ using System.Reflection;
+
+ using Castle.Core.Interceptor;
+
+ public class SelectAllSelector : IInterceptorSelector
+ {
+ public static int Instances;
+ public static int Calls;
+
+ public SelectAllSelector()
+ {
+ Instances++;
+ }
+
+ public IInterceptor[] SelectInterceptors(Type type, MethodInfo
method, IInterceptor[] interceptors)
+ {
+ Calls++;
+ return interceptors;
+ }
+ }
+}
File [added]: SelectAllSelector.cs
Delta lines: +2 -1
===================================================================
--- InversionOfControl/trunk/src/InversionOfControl-vs2008.sln 2010-01-15
16:53:40 UTC (rev 6690)
+++ InversionOfControl/trunk/src/InversionOfControl-vs2008.sln 2010-01-15
19:14:07 UTC (rev 6691)
@@ -1,4 +1,4 @@
-Microsoft Visual Studio Solution File, Format Version 10.00
+Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items",
"Solution Items", "{F9A88F20-64E5-442C-8C20-10C69A39EF4C}"
ProjectSection(SolutionItems) = preProject
@@ -59,4 +59,5 @@
GlobalSection(TextTemplating) = postSolution
TextTemplating = 1
EndGlobalSection
+GlobalSection(NDepend) = preSolution Project =
.\InversionOfControl-vs2008.ndproj EndGlobalSection
Directory: /InversionOfControl/trunk/src/Castle.Windsor.Tests/Components/
=========================================================================
File [modified]: SimpleMixIn.cs
Delta lines: +53 -4
===================================================================
--- InversionOfControl/trunk/src/Castle.Windsor.Tests/InterceptorsTestCase.cs
2010-01-15 16:53:40 UTC (rev 6690)
+++ InversionOfControl/trunk/src/Castle.Windsor.Tests/InterceptorsTestCase.cs
2010-01-15 19:14:07 UTC (rev 6691)
@@ -12,7 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-
namespace Castle.Windsor.Tests
{
using System;
@@ -22,6 +21,7 @@
using Castle.Core.Interceptor;
using Castle.MicroKernel;
using Castle.MicroKernel.Handlers;
+ using Castle.MicroKernel.Proxy;
using Castle.MicroKernel.Registration;
using Castle.Windsor.Tests.Components;
@@ -141,10 +141,59 @@
public void Xml_Component_With_Non_invalid_Interceptor_throws()
{
Assert.Throws(typeof(Exception), () =>
- container.Install(
-
Windsor.Installer.Configuration.FromXmlFile(
-
ConfigHelper.ResolveConfigPath("InterceptorsInvalid.config"))));
+ container.Install(
+
Windsor.Installer.Configuration.FromXmlFile(
+
ConfigHelper.ResolveConfigPath("InterceptorsInvalid.config"))));
}
+
+ [Test]
+ public void Xml_mixin()
+ {
+
container.Install(Windsor.Installer.Configuration.FromXmlFile(ConfigHelper.ResolveConfigPath("Mixins.config")));
+ service =
container.Resolve<CalculatorService>("ValidComponent");
+
+ Assert.IsInstanceOf<ISimpleMixIn>(service);
+
+ ((ISimpleMixIn)service).DoSomething();
+ }
+
+ [Test]
+ public void Xml_additionalInterfaces()
+ {
+
container.Install(Windsor.Installer.Configuration.FromXmlFile(ConfigHelper.ResolveConfigPath("AdditionalInterfaces.config")));
+ service =
container.Resolve<CalculatorService>("ValidComponent");
+
+ Assert.IsInstanceOf<ISimpleMixIn>(service);
+
+ Assert.Throws(typeof(System.NotImplementedException),
() =>
+
+ ((ISimpleMixIn)service).DoSomething());
+ }
+
+ [Test]
+ public void Xml_hook_and_selector()
+ {
+ container.Install(
+
Windsor.Installer.Configuration.FromXmlFile(ConfigHelper.ResolveConfigPath("InterceptorsWithHookAndSelector.config")));
+ var model =
this.container.Kernel.GetHandler("ValidComponent").ComponentModel;
+ var options = ProxyUtil.ObtainProxyOptions(model,
false);
+
+ Assert.IsNotNull(options);
+ Assert.IsNotNull(options.Selector);
+ Assert.IsNotNull(options.Hook);
+ Assert.AreEqual(0, SelectAllSelector.Instances);
+ Assert.AreEqual(0, ProxyAllHook.Instances);
+
+ service =
this.container.Resolve<CalculatorService>("ValidComponent");
+
+ Assert.AreEqual(1, SelectAllSelector.Instances);
+ Assert.AreEqual(0, SelectAllSelector.Calls);
+ Assert.AreEqual(1, ProxyAllHook.Instances);
+
+ service.Sum(2, 2);
+
+ Assert.AreEqual(1, SelectAllSelector.Calls);
+ }
#endif
[Test]
Directory:
/InversionOfControl/trunk/src/Castle.MicroKernel/ModelBuilder/Inspectors/
====================================================================================
File [added]: AdditionalInterfacesInspector.cs
Delta lines: +55 -11
===================================================================
---
InversionOfControl/trunk/src/Castle.MicroKernel/ModelBuilder/Inspectors/InterceptorInspector.cs
2010-01-15 16:53:40 UTC (rev 6690)
+++
InversionOfControl/trunk/src/Castle.MicroKernel/ModelBuilder/Inspectors/InterceptorInspector.cs
2010-01-15 19:14:07 UTC (rev 6691)
@@ -1,4 +1,4 @@
-// Copyright 2004-2009 Castle Project - http://www.castleproject.org/
+// Copyright 2004-2010 Castle Project - http://www.castleproject.org/
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -15,6 +15,10 @@
namespace Castle.MicroKernel.ModelBuilder.Inspectors
{
using System;
+
+ using Castle.Core.Configuration;
+ using Castle.Core.Interceptor;
+ using Castle.MicroKernel.Proxy;
using Castle.MicroKernel.Util;
using Castle.Core;
@@ -55,34 +59,74 @@
model.Interceptors.Add(reference);
model.Dependencies.Add(CreateDependencyModel(reference));
}
+
+ var options = ProxyUtil.ObtainProxyOptions(model, true);
+ CollectSelector(interceptors, options);
+ CollectHook(interceptors, options);
}
+ protected virtual void CollectHook(IConfiguration interceptors,
ProxyOptions options)
+ {
+ var hook = interceptors.Attributes["hook"];
+ if (hook == null)
+ {
+ return;
+ }
+
+ if (!ReferenceExpressionUtil.IsReference(hook))
+ {
+ throw new Exception(
+ String.Format("The value for the hook
must be a reference to a component (Currently {0})", hook));
+ }
+
+ var componentKey =
ReferenceExpressionUtil.ExtractComponentKey(hook);
+ options.Hook = new
ComponentReference<IProxyHook>(componentKey);
+ }
+
+ protected virtual void CollectSelector(IConfiguration
interceptors, ProxyOptions options)
+ {
+ var selector = interceptors.Attributes["selector"];
+ if (selector == null)
+ {
+ return;
+ }
+
+ if (!ReferenceExpressionUtil.IsReference(selector))
+ {
+ throw new Exception(
+ String.Format("The value for the
selector must be a reference to a component (Currently {0})", selector));
+ }
+
+ var componentKey =
ReferenceExpressionUtil.ExtractComponentKey(selector);
+ options.Selector = new
ComponentReference<IInterceptorSelector>(componentKey);
+ }
+
protected virtual void CollectFromAttributes(ComponentModel
model)
{
- if (!model.Implementation.IsDefined(
typeof(InterceptorAttribute), true ))
+ if
(!model.Implementation.IsDefined(typeof(InterceptorAttribute), true))
{
return;
}
object[] attributes =
model.Implementation.GetCustomAttributes(true);
- foreach(object attribute in attributes)
+ foreach (object attribute in attributes)
{
if (attribute is InterceptorAttribute)
{
InterceptorAttribute attr = (attribute
as InterceptorAttribute);
- AddInterceptor(
- attr.Interceptor,
- model.Interceptors );
+ AddInterceptor(
+ attr.Interceptor,
+ model.Interceptors);
- model.Dependencies.Add(
-
CreateDependencyModel(attr.Interceptor) );
+ model.Dependencies.Add(
+
CreateDependencyModel(attr.Interceptor));
}
}
}
- protected DependencyModel
CreateDependencyModel(InterceptorReference interceptor)
+ protected virtual DependencyModel
CreateDependencyModel(InterceptorReference interceptor)
{
if (string.IsNullOrEmpty(interceptor.ComponentKey))
{
@@ -92,9 +136,10 @@
return new
DependencyModel(DependencyType.ServiceOverride, interceptor.ComponentKey,
interceptor.ServiceType, false);
}
- protected void AddInterceptor(InterceptorReference
interceptorRef, InterceptorReferenceCollection interceptors)
+ protected virtual void AddInterceptor(InterceptorReference
interceptorRef, InterceptorReferenceCollection interceptors)
{
- interceptors.Add( interceptorRef );
+ interceptors.Add(interceptorRef);
}
}
}
File [modified]: InterceptorInspector.cs
Delta lines: +59 -0
===================================================================
---
InversionOfControl/trunk/src/Castle.MicroKernel/ModelBuilder/Inspectors/MixinInspector.cs
(rev 0)
+++
InversionOfControl/trunk/src/Castle.MicroKernel/ModelBuilder/Inspectors/MixinInspector.cs
2010-01-15 19:14:07 UTC (rev 6691)
@@ -0,0 +1,59 @@
+// Copyright 2004-2010 Castle Project - http://www.castleproject.org/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+namespace Castle.MicroKernel.ModelBuilder.Inspectors
+{
+ using System;
+
+ using Castle.Core;
+ using Castle.MicroKernel.Proxy;
+ using Castle.MicroKernel.Util;
+
+#if !(SILVERLIGHT)
+ [Serializable]
+#endif
+ public class MixinInspector : IContributeComponentModelConstruction
+ {
+ public void ProcessModel(IKernel kernel, ComponentModel model)
+ {
+ if (model.Configuration == null) return;
+
+ var mixins = model.Configuration.Children["mixins"];
+ if (mixins == null) return;
+
+ var options = ProxyUtil.ObtainProxyOptions(model, true);
+ foreach (var mixin in mixins.Children)
+ {
+ var value = mixin.Value;
+
+ if (!ReferenceExpressionUtil.IsReference(value))
+ {
+ throw new Exception(
+ String.Format("The value for
the mixin must be a reference to a component (Currently {0})", value));
+ }
+
+ var componentKey =
ReferenceExpressionUtil.ExtractComponentKey(value);
+ var mixIn = new
ComponentReference<object>(componentKey);
+ options.AddMixinReference(mixIn);
+
model.Dependencies.Add(CreateDependencyModel(componentKey));
+ }
+
+ }
+
+ protected DependencyModel CreateDependencyModel(string
componentKey)
+ {
+ return new
DependencyModel(DependencyType.ServiceOverride, componentKey, typeof(object),
false);
+ }
+ }
+}
File [added]: MixinInspector.cs
Delta lines: +55 -0
===================================================================
--- InversionOfControl/trunk/src/Castle.MicroKernel/Proxy/ComponentReference.cs
(rev 0)
+++ InversionOfControl/trunk/src/Castle.MicroKernel/Proxy/ComponentReference.cs
2010-01-15 19:14:07 UTC (rev 6691)
@@ -0,0 +1,55 @@
+// Copyright 2004-2010 Castle Project - http://www.castleproject.org/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+namespace Castle.MicroKernel.Proxy
+{
+ using System;
+
+ /// <summary>
+ /// Reference to component obtained from a container.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ public class ComponentReference<T> : IReference<T>
+ {
+ private readonly string componentKey;
+
+ public ComponentReference(string componentKey)
+ {
+ if (componentKey == null)
+ {
+ throw new ArgumentNullException("componentKey");
+ }
+
+ this.componentKey = componentKey;
+ }
+
+ public T Resolve(IKernel kernel, CreationContext context)
+ {
+ var handler = kernel.GetHandler(this.componentKey);
+ if (handler == null)
+ {
+ throw new Exception(string.Format("Component
{0} could not be resolved. Make sure you didn't misspell the name, and that
component is registered.", componentKey));
+ }
+
+ try
+ {
+ return (T)handler.Resolve(context);
+ }
+ catch (InvalidCastException e)
+ {
+ throw new Exception(string.Format("Component
{0} is not compatible with type {1}.", componentKey, typeof(T)), e);
+ }
+ }
+ }
+}
Directory: /InversionOfControl/trunk/src/Castle.Windsor/Installer/
==================================================================
File [modified]: DefaultComponentInstaller.cs
Delta lines: +17 -3
===================================================================
--- InversionOfControl/trunk/src/Castle.Windsor/Proxy/AbstractProxyFactory.cs
2010-01-15 16:53:40 UTC (rev 6690)
+++ InversionOfControl/trunk/src/Castle.Windsor/Proxy/AbstractProxyFactory.cs
2010-01-15 19:14:07 UTC (rev 6691)
@@ -16,6 +16,8 @@
{
using System;
using System.Collections.Generic;
+ using System.Linq;
+
using Castle.Core;
using Castle.Core.Interceptor;
using Castle.MicroKernel;
@@ -38,12 +40,24 @@
public bool ShouldCreateProxy(ComponentModel model)
{
- foreach(IModelInterceptorsSelector selector in
selectors)
+ foreach(var selector in selectors)
{
if (selector.HasInterceptors(model))
return true;
}
- return model.Interceptors.HasInterceptors;
+
+ if (model.Interceptors.HasInterceptors)
+ {
+ return true;
+ }
+
+ var options = ProxyUtil.ObtainProxyOptions(model,
false);
+ if (options == null)
+ {
+ return false;
+ }
+
+ return options.MixIns.Any() ||
options.AdditionalInterfaces.Any();
}
/// <summary>
@@ -88,7 +102,7 @@
catch(InvalidCastException)
{
String message = String.Format(
- "An interceptor registered for
{0} doesnt implement the IInterceptor interface",
+ "An interceptor registered for
{0} doesn't implement the IInterceptor interface",
model.Name);
Directory:
/InversionOfControl/trunk/src/Castle.MicroKernel/Registration/Interceptor/
=====================================================================================
File [modified]: InterceptorSelectorDescriptor.cs
Delta lines: +1 -1
===================================================================
---
InversionOfControl/trunk/src/Castle.MicroKernel.Tests/Registration/ComponentRegistrationTestCase.cs
2010-01-15 16:53:40 UTC (rev 6690)
+++
InversionOfControl/trunk/src/Castle.MicroKernel.Tests/Registration/ComponentRegistrationTestCase.cs
2010-01-15 19:14:07 UTC (rev 6691)
@@ -71,7 +71,7 @@
var proxyOptions =
ProxyUtil.ObtainProxyOptions(handler.ComponentModel, false);
Assert.IsNotNull(proxyOptions);
- Assert.AreEqual(selector, proxyOptions.Selector);
+ Assert.AreEqual( selector, proxyOptions.Selector.Resolve( null,
null ) );
}
Directory: /InversionOfControl/trunk/src/Castle.MicroKernel/ModelBuilder/
=========================================================================
File [modified]: DefaultComponentModelBuilder.cs
Delta lines: +60 -0
===================================================================
---
InversionOfControl/trunk/src/Castle.MicroKernel/ModelBuilder/Inspectors/AdditionalInterfacesInspector.cs
(rev 0)
+++
InversionOfControl/trunk/src/Castle.MicroKernel/ModelBuilder/Inspectors/AdditionalInterfacesInspector.cs
2010-01-15 19:14:07 UTC (rev 6691)
@@ -0,0 +1,61 @@
+// Copyright 2004-2010 Castle Project - http://www.castleproject.org/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+namespace Castle.MicroKernel.ModelBuilder.Inspectors
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+
+ using Castle.Core;
+ using Castle.MicroKernel.Proxy;
+
+#if !(SILVERLIGHT)
+ [Serializable]
+#endif
+ public class AdditionalInterfacesInspector :
IContributeComponentModelConstruction
+ {
+ public void ProcessModel(IKernel kernel, ComponentModel model)
+ {
+ if (model.Configuration == null) return;
+
+ var interfaces =
model.Configuration.Children["additionalInterfaces"];
+ if (interfaces == null) return;
+
+ var list = new HashSet<Type>();
+ foreach (var @interface in interfaces.Children
+ .Where(c => c.Name.Equals("add",
StringComparison.InvariantCultureIgnoreCase)))
+ {
+ var interfaceTypeName =
@interface.Attributes["interface"];
+ list.Add(ObtainType(interfaceTypeName));
+ }
+
+ var options = ProxyUtil.ObtainProxyOptions(model, true);
+ options.AddAdditionalInterfaces(list.ToArray());
+ }
+
+ private static Type ObtainType(String typeName)
+ {
+ try
+ {
+ return Type.GetType(typeName, true, false);
+ }
+ catch (Exception e)
+ {
+ var message = String.Format("The type name {0}
could not be located.", typeName);
+ throw new Exception(message, e);
+ }
+ }
+ }
Directory: /InversionOfControl/trunk/src/Castle.MicroKernel/Proxy/
==================================================================
File [added]: ComponentReference.cs
Delta lines: +33 -0
===================================================================
--- InversionOfControl/trunk/src/Castle.MicroKernel/Proxy/IReference.cs
(rev 0)
+++ InversionOfControl/trunk/src/Castle.MicroKernel/Proxy/IReference.cs
2010-01-15 19:14:07 UTC (rev 6691)
@@ -0,0 +1,33 @@
+// Copyright 2004-2010 Castle Project - http://www.castleproject.org/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+namespace Castle.MicroKernel.Proxy
+{
+ /// <summary>
+ /// Represents obtained just in time object.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ public interface IReference<T>
+ {
+ /// <summary>
+ /// Resolves object referenced by this reference, optionally
using provided <see cref="kernel"/>.
+ /// If object is resolved from the kernel, the <see
cref="context"/> should be used to guard
+ /// against against cyclic dependencies.
+ /// </summary>
+ /// <param name="kernel"></param>
+ /// <param name="context"></param>
+ /// <returns></returns>
+ T Resolve(IKernel kernel, CreationContext context);
+ }
+}
File [added]: IReference.cs
Delta lines: +35 -0
===================================================================
--- InversionOfControl/trunk/src/Castle.MicroKernel/Proxy/InstanceReference.cs
(rev 0)
+++ InversionOfControl/trunk/src/Castle.MicroKernel/Proxy/InstanceReference.cs
2010-01-15 19:14:07 UTC (rev 6691)
@@ -0,0 +1,35 @@
+// Copyright 2004-2010 Castle Project - http://www.castleproject.org/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+namespace Castle.MicroKernel.Proxy
+{
+ /// <summary>
+ /// Represents a reference to an existing object.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ public class InstanceReference<T> : IReference<T>
+ {
+ private readonly T instance;
+
+ public InstanceReference(T instance)
+ {
+ this.instance = instance;
+ }
+
+ public T Resolve(IKernel kernel, CreationContext context)
+ {
+ return instance;
+ }
+ }
+}
File [added]: InstanceReference.cs
Delta lines: +48 -55
===================================================================
--- InversionOfControl/trunk/src/Castle.MicroKernel/Proxy/ProxyOptions.cs
2010-01-15 16:53:40 UTC (rev 6690)
+++ InversionOfControl/trunk/src/Castle.MicroKernel/Proxy/ProxyOptions.cs
2010-01-15 19:14:07 UTC (rev 6691)
@@ -24,82 +24,51 @@
/// </summary>
public class ProxyOptions
{
- private IProxyHook hook;
- private IInterceptorSelector selector;
private List<Type> interfaceList;
- private List<object> mixInList;
- private bool useSingleInterfaceProxy;
-#if (!SILVERLIGHT)
- private bool useMarshalByRefAsBaseClass;
-#endif
- private bool allowChangeTarget;
- private bool omitTarget;
+ private List<IReference<object>> mixInList;
/// <summary>
/// Initializes a new instance of the <see
cref="ProxyOptions"/> class.
/// </summary>
public ProxyOptions()
{
- useSingleInterfaceProxy = false;
- omitTarget = false;
+ UseSingleInterfaceProxy = false;
+ OmitTarget = false;
}
/// <summary>
/// Gets or sets the proxy hook.
/// </summary>
- public IProxyHook Hook
- {
- get { return hook; }
- set { hook = value; }
- }
+ public IReference<IProxyHook> Hook { get; set; }
/// <summary>
/// Gets or sets the interceptor selector.
/// </summary>
- public IInterceptorSelector Selector
- {
- get { return selector; }
- set { selector = value; }
- }
+ public IReference<IInterceptorSelector> Selector { get; set; }
/// <summary>
/// Determines if the proxied component uses a target.
/// </summary>
- public bool OmitTarget
- {
- get { return omitTarget; }
- set { omitTarget = value; }
- }
+ public bool OmitTarget { get; set; }
/// <summary>
/// Determines if the proxied component can change targets.
/// </summary>
- public bool AllowChangeTarget
- {
- get { return allowChangeTarget; }
- set { allowChangeTarget = value; }
- }
+ public bool AllowChangeTarget { get; set; }
/// <summary>
/// Determines if the proxied component should only include
/// the service interface.
/// </summary>
- public bool UseSingleInterfaceProxy
- {
- get { return useSingleInterfaceProxy; }
- set { useSingleInterfaceProxy = value; }
- }
+ public bool UseSingleInterfaceProxy { get; set; }
#if (!SILVERLIGHT)
/// <summary>
/// Determines if the interface proxied component should
inherit
/// from <see cref="MarshalByRefObject"/>
/// </summary>
- public bool UseMarshalByRefAsBaseClass
- {
- get { return useMarshalByRefAsBaseClass; }
- set { useMarshalByRefAsBaseClass = value; }
- }
+ public bool UseMarshalByRefAsBaseClass { get; set; }
+
#endif
/// <summary>
@@ -112,7 +81,7 @@
{
if (interfaceList != null)
{
- return (Type[]) interfaceList.ToArray();
+ return interfaceList.ToArray();
}
return new Type[0];
@@ -123,16 +92,19 @@
/// Gets the mix ins to integrate.
/// </summary>
/// <value>The interfaces.</value>
- public object[] MixIns
+ public IEnumerable<IReference<object>> MixIns
{
get
{
- if (mixInList != null)
+ if (mixInList == null)
{
- return (object[])mixInList.ToArray();
+ yield break;
}
- return new object[0];
+ foreach (var reference in this.mixInList)
+ {
+ yield return reference;
+ }
}
}
@@ -168,13 +140,34 @@
if (mixInList == null)
{
- mixInList = new List<object>();
+ mixInList = new List<IReference<object>>();
}
- mixInList.AddRange(mixIns);
+ foreach (var mixIn in mixIns)
+ {
+ mixInList.Add(new
InstanceReference<object>(mixIn));
+ }
}
/// <summary>
+ /// Adds the additional mix in to integrate.
+ /// </summary>
+ /// <param name="mixIn">The mix in.</param>
+ public void AddMixinReference(IReference<object> mixIn)
+ {
+ if (mixIn == null)
+ {
+ throw new ArgumentNullException("mixIn");
+ }
+
+ if (mixInList == null)
+ {
+ mixInList = new List<IReference<object>>();
+ }
+ mixInList.Add(mixIn);
+ }
+
+ /// <summary>
/// Equalses the specified obj.
/// </summary>
/// <param name="obj">The obj.</param>
@@ -182,12 +175,12 @@
public override bool Equals(object obj)
{
if (this == obj) return true;
- ProxyOptions proxyOptions = obj as ProxyOptions;
+ var proxyOptions = obj as ProxyOptions;
if (proxyOptions == null) return false;
- if (!Equals(hook, proxyOptions.hook)) return false;
- if (!Equals(selector, proxyOptions.selector)) return
false;
- if (!Equals(useSingleInterfaceProxy,
proxyOptions.useSingleInterfaceProxy)) return false;
- if (!Equals(omitTarget, proxyOptions.omitTarget))
return false;
+ if (!Equals(this.Hook, proxyOptions.Hook)) return false;
+ if (!Equals(this.Selector, proxyOptions.Selector))
return false;
+ if (!Equals(this.UseSingleInterfaceProxy,
proxyOptions.UseSingleInterfaceProxy)) return false;
+ if (!Equals(this.OmitTarget, proxyOptions.OmitTarget))
return false;
if (!AdditionalInterfacesAreEquals(proxyOptions))
return false;
return MixInsAreEquals(proxyOptions);
}
@@ -208,7 +201,7 @@
if (!Equals(interfaceList == null,
proxyOptions.interfaceList == null)) return false;
if (interfaceList == null) return true; //both are
null, nothing more to check
if (interfaceList.Count !=
proxyOptions.interfaceList.Count) return false;
- for(int i = 0; i < interfaceList.Count; ++i)
+ for (int i = 0; i < interfaceList.Count; ++i)
{
if
(!proxyOptions.interfaceList.Contains(interfaceList[0])) return false;
}
@@ -233,7 +226,7 @@
if (items == null) return result;
- foreach(object item in items)
+ foreach (object item in items)
{
result = 29 * result + item.GetHashCode();
File [modified]: ProxyOptions.cs
Delta lines: +1 -1
===================================================================
---
InversionOfControl/trunk/src/Castle.MicroKernel/Registration/Interceptor/InterceptorSelectorDescriptor.cs
2010-01-15 16:53:40 UTC (rev 6690)
+++
InversionOfControl/trunk/src/Castle.MicroKernel/Registration/Interceptor/InterceptorSelectorDescriptor.cs
2010-01-15 19:14:07 UTC (rev 6691)
@@ -30,7 +30,7 @@
protected internal override void ApplyToModel(IKernel kernel,
ComponentModel model)
{
ProxyOptions options =
ProxyUtil.ObtainProxyOptions(model, true);
- options.Selector = selector;
+ options.Selector = new
InstanceReference<IInterceptorSelector>( selector );
}
}
}
Directory: /InversionOfControl/trunk/src/Castle.Windsor/Proxy/
==============================================================
File [modified]: AbstractProxyFactory.cs
Delta lines: +19 -20
===================================================================
--- InversionOfControl/trunk/src/Castle.Windsor/Proxy/DefaultProxyFactory.cs
2010-01-15 16:53:40 UTC (rev 6690)
+++ InversionOfControl/trunk/src/Castle.Windsor/Proxy/DefaultProxyFactory.cs
2010-01-15 19:14:07 UTC (rev 6691)
@@ -73,7 +73,7 @@
IInterceptor[] interceptors =
ObtainInterceptors(kernel, model, context);
ProxyOptions proxyOptions =
ProxyUtil.ObtainProxyOptions(model, true);
- ProxyGenerationOptions proxyGenOptions =
CreateProxyGenerationOptionsFrom(proxyOptions);
+ ProxyGenerationOptions proxyGenOptions =
CreateProxyGenerationOptionsFrom(proxyOptions, kernel, context);
CustomizeOptions(proxyGenOptions, kernel, model,
constructorArguments);
@@ -88,8 +88,8 @@
}
else if (proxyOptions.AllowChangeTarget)
{
- proxy =
generator.CreateInterfaceProxyWithTargetInterface(model.Service, interfaces,
target,
-
proxyGenOptions, interceptors);
+ proxy =
generator.CreateInterfaceProxyWithTargetInterface(model.Service, interfaces,
target,
+
proxyGenOptions, interceptors);
}
else
{
@@ -99,7 +99,7 @@
}
proxy =
generator.CreateInterfaceProxyWithTarget(model.Service, interfaces,
-
target,
proxyGenOptions, interceptors);
+
target, proxyGenOptions, interceptors);
}
}
else
@@ -113,18 +113,19 @@
return proxy;
}
- protected static ProxyGenerationOptions
CreateProxyGenerationOptionsFrom(ProxyOptions proxyOptions)
+ protected static ProxyGenerationOptions
CreateProxyGenerationOptionsFrom(ProxyOptions proxyOptions, IKernel kernel,
CreationContext context)
{
- ProxyGenerationOptions proxyGenOptions = new
ProxyGenerationOptions();
-
+ var proxyGenOptions = new ProxyGenerationOptions();
if (proxyOptions.Hook != null)
{
- proxyGenOptions.Hook = new
ProxyGenerationHookAdapter(proxyOptions.Hook);
+ var hook = proxyOptions.Hook.Resolve(kernel,
context);
+ proxyGenOptions.Hook = new
ProxyGenerationHookAdapter(hook);
}
if (proxyOptions.Selector != null)
{
- proxyGenOptions.Selector =
proxyOptions.Selector;
+ var selector =
proxyOptions.Selector.Resolve(kernel, context);
+ proxyGenOptions.Selector = selector;
}
#if (!SILVERLIGHT)
if (proxyOptions.UseMarshalByRefAsBaseClass)
@@ -132,24 +133,23 @@
proxyGenOptions.BaseTypeForInterfaceProxy =
typeof(MarshalByRefObject);
}
#endif
- foreach (object mixIn in proxyOptions.MixIns)
+ foreach (var mixInReference in proxyOptions.MixIns)
{
+ var mixIn = mixInReference.Resolve(kernel,
context);
proxyGenOptions.AddMixinInstance(mixIn);
}
return proxyGenOptions;
}
- protected virtual void CustomizeProxy(object proxy,
ProxyGenerationOptions options,
- IKernel kernel,
ComponentModel model)
+ protected virtual void CustomizeProxy(object proxy,
ProxyGenerationOptions options, IKernel kernel, ComponentModel model)
{
}
- protected virtual void CustomizeOptions(ProxyGenerationOptions
options, IKernel kernel,
- ComponentModel model,
object[] arguments)
+ protected virtual void CustomizeOptions(ProxyGenerationOptions
options, IKernel kernel, ComponentModel model, object[] arguments)
{
}
-
+
/// <summary>
/// Determines if the component requiries a target instance for
proxying.
/// </summary>
@@ -158,23 +158,22 @@
/// <returns>true if an instance is required.</returns>
public override bool RequiresTargetInstance(IKernel kernel,
ComponentModel model)
{
- ProxyOptions proxyOptions =
ProxyUtil.ObtainProxyOptions(model, true);
+ var proxyOptions = ProxyUtil.ObtainProxyOptions(model,
true);
return model.Service.IsInterface &&
!proxyOptions.OmitTarget;
}
protected Type[] CollectInterfaces(Type[] interfaces,
ComponentModel model)
{
- Type[] modelInterfaces =
model.Implementation.FindInterfaces(
- new TypeFilter(EmptyTypeFilter), model.Service);
+ var modelInterfaces =
model.Implementation.FindInterfaces(EmptyTypeFilter, model.Service);
if (interfaces == null || interfaces.Length == 0)
{
interfaces = modelInterfaces;
}
- else if (modelInterfaces != null &&
modelInterfaces.Length > 0)
+ else if (modelInterfaces.Length > 0)
{
- Type[] allInterfaces = new
Type[interfaces.Length + modelInterfaces.Length];
+ var allInterfaces = new Type[interfaces.Length
+ modelInterfaces.Length];
interfaces.CopyTo(allInterfaces, 0);
modelInterfaces.CopyTo(allInterfaces,
interfaces.Length);
File [modified]: DefaultProxyFactory.cs
Delta lines: +11 -0
===================================================================
---
InversionOfControl/trunk/src/Castle.Windsor.Tests/AdditionalInterfaces.config
(rev 0)
+++
InversionOfControl/trunk/src/Castle.Windsor.Tests/AdditionalInterfaces.config
2010-01-15 19:14:07 UTC (rev 6691)
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+ <components>
+ <component
+ id="ValidComponent"
+
type="Castle.Windsor.Tests.Components.CalculatorService, Castle.Windsor.Tests">
+ <additionalInterfaces>
+ <add
interface="Castle.Windsor.Tests.Components.ISimpleMixIn, Castle.Windsor.Tests"
/>
+ </additionalInterfaces>
+ </component>
+ </components>
Directory: /InversionOfControl/trunk/src/Castle.MicroKernel.Tests/Registration/
===============================================================================
File [modified]: ComponentRegistrationTestCase.cs
Delta lines: +1 -1
===================================================================
---
InversionOfControl/trunk/src/Castle.Windsor/Installer/DefaultComponentInstaller.cs
2010-01-15 16:53:40 UTC (rev 6690)
+++
InversionOfControl/trunk/src/Castle.Windsor/Installer/DefaultComponentInstaller.cs
2010-01-15 19:14:07 UTC (rev 6691)
@@ -118,7 +118,7 @@
var forwarded = new List<Type>();
foreach (var forwardedType in forwardedTypes.Children
- .Where(c => c.Name.Equals("add",
StringComparison.OrdinalIgnoreCase)))
+ .Where(c => c.Name.Equals("add",
StringComparison.InvariantCultureIgnoreCase)))
{
var forwardedServiceTypeName =
forwardedType.Attributes["service"];
Directory: /InversionOfControl/trunk/src/
=========================================
File [modified]: InversionOfControl-vs2008.sln
Delta lines: +0 -0
===================================================================
--
You received this message because you are subscribed to the Google Groups
"Castle Project Commits" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/castle-project-commits?hl=en.