User: xtoff
Date: 2009/12/05 08:50 AM
Added:
/Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/
PerWcfSessionLifestyleTestCase.cs
/Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/Components/
IOne.cs, IServiceWithSession.cs, ITwo.cs, One.cs, ServiceWithSession.cs,
Two.cs
/Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/Lifestyles/
IOperationContextProvider.cs, IWcfLifestyle.cs,
LifestyleRegistrationExtensions.cs, OperationContextProvider.cs,
PerChannelLifestyleExtension.cs, PerWcfSessionLifestyle.cs
Modified:
/Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/
Castle.Facilities.WcfIntegration.Tests-vs2008.csproj, WcfServiceFixture.cs
/Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/
Castle.Facilities.WcfIntegration-vs2008.csproj
/Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/Client/Proxy/
WcfProxyGenerationHook.cs
Log:
- added intial implementation of per-WCF-Session lifetime.
File Changes:
Directory: /Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/
======================================================================
File [modified]: Castle.Facilities.WcfIntegration-vs2008.csproj
Delta lines: +1 -0
===================================================================
---
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/Client/Proxy/WcfProxyGenerationHook.cs
2009-12-05 08:38:19 UTC (rev 6391)
+++
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/Client/Proxy/WcfProxyGenerationHook.cs
2009-12-05 15:50:04 UTC (rev 6392)
@@ -32,6 +32,7 @@
public bool ShouldInterceptMethod(Type type, MethodInfo
methodInfo)
{
+ // NOTE: This is fixed now. This code can be
uncommented and Selector does not have to have this responsibility anymore
// BUG: Due to... illogical behavior of DP this will
produce illformed proxy types.
// We have to move this piece of logic to
InterceptorSelector, and move it back when the bug gets fixed.
Directory: /Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/
============================================================================
File [modified]: Castle.Facilities.WcfIntegration.Tests-vs2008.csproj
Delta lines: +21 -0
===================================================================
---
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/Components/IOne.cs
(rev 0)
+++
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/Components/IOne.cs
2009-12-05 15:50:04 UTC (rev 6392)
@@ -0,0 +1,21 @@
+// 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.Facilities.WcfIntegration.Tests.Components
+{
+ public interface IOne
+ {
+ void Do(string s);
+ }
+}
File [added]: PerWcfSessionLifestyleTestCase.cs
Delta lines: +1 -3
===================================================================
---
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/WcfServiceFixture.cs
2009-12-05 08:38:19 UTC (rev 6391)
+++
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/WcfServiceFixture.cs
2009-12-05 15:50:04 UTC (rev 6392)
@@ -17,12 +17,10 @@
using System;
using System.Collections.Generic;
using System.ServiceModel;
- using System.ServiceModel.Description;
+
using Castle.Core;
using Castle.Core.Interceptor;
- using Castle.Facilities.WcfIntegration.Demo;
using Castle.Facilities.WcfIntegration.Tests.Behaviors;
- using Castle.MicroKernel;
using Castle.MicroKernel.Registration;
using Castle.Windsor;
File [modified]: WcfServiceFixture.cs
Delta lines: +0 -0
===================================================================
Directory:
/Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/Components/
=======================================================================================
File [added]: IOne.cs
Delta lines: +34 -0
===================================================================
---
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/Components/IServiceWithSession.cs
(rev 0)
+++
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/Components/IServiceWithSession.cs
2009-12-05 15:50:04 UTC (rev 6392)
@@ -0,0 +1,34 @@
+// 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.Facilities.WcfIntegration.Tests.Components
+{
+ using System.ServiceModel;
+
+ [ServiceContract(SessionMode = SessionMode.Required)]
+ public interface IServiceWithSession
+ {
+ [OperationContract(IsInitiating = true, IsTerminating = false)]
+ void Initiating(string a);
+
+ [OperationContract(IsInitiating = false, IsTerminating = false)]
+ void Operation1(string a);
+
+ [OperationContract(IsInitiating = false, IsTerminating = false)]
+ void Operation2(string a);
+
+ [OperationContract(IsInitiating = false, IsTerminating = true)]
+ void Terminating();
+ }
+}
File [added]: IServiceWithSession.cs
Delta lines: +21 -0
===================================================================
---
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/Components/ITwo.cs
(rev 0)
+++
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/Components/ITwo.cs
2009-12-05 15:50:04 UTC (rev 6392)
@@ -0,0 +1,21 @@
+// 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.Facilities.WcfIntegration.Tests.Components
+{
+ public interface ITwo
+ {
+ void Do(string s);
+ }
+}
File [added]: ITwo.cs
Delta lines: +31 -0
===================================================================
---
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/Components/One.cs
(rev 0)
+++
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/Components/One.cs
2009-12-05 15:50:04 UTC (rev 6392)
@@ -0,0 +1,31 @@
+// 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.Facilities.WcfIntegration.Tests.Components
+{
+ public class One : IOne
+ {
+ private string arg;
+
+ public string Arg
+ {
+ get { return arg; }
+ }
+
+ public void Do(string s)
+ {
+ arg += s;
+ }
+ }
+}
File [added]: One.cs
Delta lines: +52 -0
===================================================================
---
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/Components/ServiceWithSession.cs
(rev 0)
+++
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/Components/ServiceWithSession.cs
2009-12-05 15:50:04 UTC (rev 6392)
@@ -0,0 +1,52 @@
+// 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.Facilities.WcfIntegration.Tests.Components
+{
+ using System.ServiceModel;
+
+ [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
+ public class ServiceWithSession : IServiceWithSession
+ {
+ private readonly IOne one;
+ private readonly ITwo two;
+ public static int InstanceCount;
+
+ public ServiceWithSession(IOne one, ITwo two)
+ {
+ this.one = one;
+ this.two = two;
+ InstanceCount++;
+ }
+
+ public void Initiating(string a)
+ {
+ one.Do(a);
+ }
+
+ public void Operation1(string a)
+ {
+ one.Do(a);
+ }
+
+ public void Operation2(string a)
+ {
+ two.Do(a);
+ }
+
+ public void Terminating()
+ {
+ }
+ }
+}
File [added]: ServiceWithSession.cs
Delta lines: +31 -0
===================================================================
---
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/Components/Two.cs
(rev 0)
+++
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/Components/Two.cs
2009-12-05 15:50:04 UTC (rev 6392)
@@ -0,0 +1,31 @@
+// 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.Facilities.WcfIntegration.Tests.Components
+{
+ public class Two : ITwo
+ {
+ private string arg;
+
+ public string Arg
+ {
+ get { return arg; }
+ }
+
+ public void Do(string s)
+ {
+ arg += s;
+ }
+ }
+}
File [added]: Two.cs
Delta lines: +136 -0
===================================================================
---
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/PerWcfSessionLifestyleTestCase.cs
(rev 0)
+++
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/PerWcfSessionLifestyleTestCase.cs
2009-12-05 15:50:04 UTC (rev 6392)
@@ -0,0 +1,136 @@
+// 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.Facilities.WcfIntegration.Tests
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.ServiceModel;
+
+ using Castle.Core;
+ using Castle.Core.Interceptor;
+ using Castle.Facilities.WcfIntegration.Lifestyles;
+ using Castle.Facilities.WcfIntegration.Tests.Behaviors;
+ using Castle.Facilities.WcfIntegration.Tests.Components;
+ using Castle.MicroKernel.Registration;
+ using Castle.Windsor;
+
+ using NUnit.Framework;
+
+ [TestFixture]
+ public class PerWcfSessionLifestyleTestCase
+ {
+ [SetUp]
+ public void SetUp()
+ {
+ windsorContainer = new WindsorContainer()
+ .AddFacility<WcfFacility>(f => f.CloseTimeout =
TimeSpan.Zero)
+ .Register(
+ Component.For<ServiceHostListener>(),
+ Component.For<CollectingInterceptor>(),
+ Component.For<UnitOfworkEndPointBehavior>(),
+ Component.For<NetDataContractFormatBehavior>(),
+
Component.For<IOne>().ImplementedBy<One>().LifeStyle.PerWcfSession().Interceptors(
+
InterceptorReference.ForType<CollectingInterceptor>()).Anywhere,
+
Component.For<ITwo>().ImplementedBy<Two>().LifeStyle.PerWcfSession().Interceptors(
+
InterceptorReference.ForType<CollectingInterceptor>()).Anywhere,
+
Component.For<IServiceWithSession>().ImplementedBy<ServiceWithSession>().LifeStyle.Transient
+ .Named("Operations")
+ .ActAs(new
DefaultServiceModel().AddEndpoints(
+ WcfEndpoint.BoundTo(new
NetTcpBinding { PortSharingEnabled = true })
+
.At("net.tcp://localhost/Operations")
+ )
+ )
+ );
+
+ client = CreateClient();
+ }
+
+ [TearDown]
+ public void TearDown()
+ {
+ windsorContainer.Dispose();
+ ServiceWithSession.InstanceCount = 0;
+ }
+
+ private IWindsorContainer windsorContainer;
+ private IServiceWithSession client;
+
+ private IServiceWithSession CreateClient()
+ {
+ return
ChannelFactory<IServiceWithSession>.CreateChannel(
+ new NetTcpBinding { PortSharingEnabled = true
}, new EndpointAddress("net.tcp://localhost/Operations"));
+ }
+
+ [Test]
+ public void
Services_should_be_reused_among_calls_within_session()
+ {
+ client.Initiating("start ");
+ client.Operation1("one ");
+ client.Operation1("and again");
+ client.Operation2("two ");
+ client.Operation2("and two again");
+ client.Terminating();
+ IGrouping<object, IInvocation>[] invocations =
windsorContainer.GetService<CollectingInterceptor>()
+ .AllInvocations
+ .GroupBy(i => i.InvocationTarget)
+ .ToArray();
+ Assert.AreEqual(2, invocations.Length);
+ var one = invocations[0].Key as One;
+ var two = invocations[1].Key as Two;
+ Assert.AreEqual("start one and again", one.Arg);
+ Assert.AreEqual("two and two again", two.Arg);
+ }
+
+ [Test]
+ public void Services_should_not_be_shared_between_two_sessions()
+ {
+ client.Initiating("Client 1");
+ client.Operation1(" Run Forrest run!");
+ client.Terminating();
+ client = CreateClient();
+ client.Initiating("Client 2");
+ client.Operation1(" welcomes you.");
+ client.Terminating();
+ var interceptor =
windsorContainer.GetService<CollectingInterceptor>();
+ IGrouping<object, IInvocation>[] invocations =
interceptor
+ .AllInvocations
+ .GroupBy(i => i.InvocationTarget)
+ .ToArray();
+
+ Assert.AreEqual(6, ServiceWithSession.InstanceCount);
+ Assert.AreEqual(2, invocations.Length);
+ var one1 = invocations[0].Key as One;
+ var one2 = invocations[1].Key as One;
+ Assert.AreEqual("Client 1 Run Forrest run!", one1.Arg);
+ Assert.AreEqual("Client 2 welcomes you.", one2.Arg);
+ }
+ }
+
+ public class CollectingInterceptor : StandardInterceptor
+ {
+ private readonly List<IInvocation> invocations = new
List<IInvocation>();
+
+ public IInvocation[] AllInvocations
+ {
+ get { return invocations.ToArray(); }
+ }
+
+ protected override void PreProceed(IInvocation invocation)
+ {
+ invocations.Add(invocation);
+ }
+ }
+}
Directory:
/Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/Lifestyles/
=================================================================================
File [added]: IOperationContextProvider.cs
Delta lines: +19 -0
===================================================================
---
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/Lifestyles/IWcfLifestyle.cs
(rev 0)
+++
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/Lifestyles/IWcfLifestyle.cs
2009-12-05 15:50:04 UTC (rev 6392)
@@ -0,0 +1,19 @@
+namespace Castle.Facilities.WcfIntegration.Lifestyles
+{
+ using System;
+
+ using Castle.MicroKernel;
+
+ /// <summary>
+ /// Contract for managing object lifestyles in the context of WCF
runtime.
+ /// </summary>
+ public interface IWcfLifestyle:ILifestyleManager
+ {
+ /// <summary>
+ /// Id of the component associated with the lifestyle manager
instance.
+ /// This Id does not have to have anything to do with the Id of
the component assigned by the container.
+ /// It is used for internal tracking purposes os the facility.
+ /// </summary>
+ Guid ComponentId { get; }
+ }
+}
File [added]: IWcfLifestyle.cs
Delta lines: +13 -0
===================================================================
---
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/Lifestyles/LifestyleRegistrationExtensions.cs
(rev 0)
+++
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/Lifestyles/LifestyleRegistrationExtensions.cs
2009-12-05 15:50:04 UTC (rev 6392)
@@ -0,0 +1,13 @@
+namespace Castle.Facilities.WcfIntegration.Lifestyles
+{
+ using Castle.MicroKernel.Registration;
+ using Castle.MicroKernel.Registration.Lifestyle;
+
+ public static class LifestyleRegistrationExtensions
+ {
+ public static ComponentRegistration<S> PerWcfSession<S>(this
LifestyleGroup<S> @group)
+ {
+ return group.Custom<PerWcfSessionLifestyle>();
+ }
+ }
+}
File [added]: LifestyleRegistrationExtensions.cs
Delta lines: +12 -0
===================================================================
---
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/Lifestyles/OperationContextProvider.cs
(rev 0)
+++
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/Lifestyles/OperationContextProvider.cs
2009-12-05 15:50:04 UTC (rev 6392)
@@ -0,0 +1,12 @@
+namespace Castle.Facilities.WcfIntegration.Lifestyles
+{
+ using System.ServiceModel;
+
+ public class OperationContextProvider : IOperationContextProvider
+ {
+ public OperationContext Current
+ {
+ get { return OperationContext.Current; }
+ }
+ }
+}
File [added]: OperationContextProvider.cs
Delta lines: +87 -0
===================================================================
---
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/Lifestyles/PerChannelLifestyleExtension.cs
(rev 0)
+++
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/Lifestyles/PerChannelLifestyleExtension.cs
2009-12-05 15:50:04 UTC (rev 6392)
@@ -0,0 +1,87 @@
+namespace Castle.Facilities.WcfIntegration//in the default namespace so that
it's visible out of the box
+{
+ using System;
+ using System.Collections.Generic;
+ using System.ServiceModel;
+
+ using Castle.Facilities.WcfIntegration.Lifestyles;
+
+ public class PerChannelLifestyleExtension : IExtension<IContextChannel>
+ {
+ private IContextChannel channel;
+ private readonly IDictionary<IWcfLifestyle, object> components
= new Dictionary<IWcfLifestyle, object>(new WCFLifestyleComparer());
+ private bool used;
+
+ /// <inheritDoc />
+ public void Attach(IContextChannel owner)
+ {
+ if(used)
+ {
+ throw new InvalidOperationException("This
instance was already used!");
+ }
+
+ if (channel != null)
+ {
+ throw new InvalidOperationException("Can't
attach twice!");
+ }
+
+ used = true;
+ channel = owner;
+ channel.Faulted += Shutdown;
+ channel.Closed += Shutdown;
+ }
+
+ private void Shutdown(object sender, EventArgs e)
+ {
+ channel.Extensions.Remove(this);
+ foreach (var component in components)
+ {
+ component.Key.Release(component.Value);
+ }
+ components.Clear();
+ }
+
+ /// <inheritDoc />
+ public void Detach(IContextChannel owner)
+ {
+ if (!used)
+ {
+ throw new InvalidOperationException("This
instance was not used!");
+ }
+ if (channel == null)
+ {
+ throw new InvalidOperationException("Can't
Detach twice or before attaching!");
+ }
+ channel.Faulted -= Shutdown;
+ channel.Closed -= Shutdown;
+ channel = null;
+ }
+
+ public object this[IWcfLifestyle manager]
+ {
+ get
+ {
+ object component;
+ components.TryGetValue(manager, out component);
+ return component;
+ }
+ set
+ {
+ components[manager] = value;
+ }
+ }
+
+ private class WCFLifestyleComparer :
IEqualityComparer<IWcfLifestyle>
+ {
+ public bool Equals(IWcfLifestyle x, IWcfLifestyle y)
+ {
+ return x.ComponentId.Equals(y.ComponentId);
+ }
+
+ public int GetHashCode(IWcfLifestyle obj)
+ {
+ return obj.ComponentId.GetHashCode();
+ }
+ }
+ }
+}
File [added]: PerChannelLifestyleExtension.cs
Delta lines: +74 -0
===================================================================
---
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/Lifestyles/PerWcfSessionLifestyle.cs
(rev 0)
+++
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/Lifestyles/PerWcfSessionLifestyle.cs
2009-12-05 15:50:04 UTC (rev 6392)
@@ -0,0 +1,74 @@
+namespace Castle.Facilities.WcfIntegration.Lifestyles
+{
+ using System;
+
+ using Castle.MicroKernel;
+ using Castle.MicroKernel.Lifestyle;
+
+ /// <summary>
+ /// Manages object instances in the context of WCF session. This means
that when a component
+ /// with this lifestyle is requested multiple times during WCF session,
the same instance will be provided.
+ /// If no WCF session is available falls back to the default behavior
of transient.
+ /// </summary>
+ public class PerWcfSessionLifestyle : AbstractLifestyleManager,
IWcfLifestyle
+ {
+ private readonly Guid id = Guid.NewGuid();
+
+ private readonly IOperationContextProvider
operationContextProvider;
+
+ public PerWcfSessionLifestyle()
+ : this(new OperationContextProvider())
+ {
+ }
+
+ public PerWcfSessionLifestyle(IOperationContextProvider
operationContextProvider)
+ {
+ if (operationContextProvider == null)
+ {
+ throw new
ArgumentNullException("operationContextProvider");
+ }
+
+ this.operationContextProvider =
operationContextProvider;
+ }
+
+ public override void Dispose()
+ {
+
+ }
+
+ public override object Resolve(CreationContext context)
+ {
+ var operation = operationContextProvider.Current;
+ if (operation == null)
+ return base.Resolve(context);
+
+ if (string.IsNullOrEmpty(operation.SessionId))
+ return base.Resolve(context);
+
+ var channel = operation.Channel;
+
+ // TODO: does this need locking?
+ var lifestyle =
channel.Extensions.Find<PerChannelLifestyleExtension>();
+
+ if (lifestyle == null)
+ {
+ lifestyle = new PerChannelLifestyleExtension();
+ channel.Extensions.Add(lifestyle);
+ }
+
+ var component = lifestyle[this];
+ if (component == null)
+ {
+ component = base.Resolve(context);
+ lifestyle[this] = component;
+ }
+
+ return component;
+ }
+
+ public Guid ComponentId
+ {
+ get { return id; }
+ }
+ }
+}
File [added]: PerWcfSessionLifestyle.cs
Delta lines: +7 -0
===================================================================
---
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/Castle.Facilities.WcfIntegration.Tests-vs2008.csproj
2009-12-05 08:38:19 UTC (rev 6391)
+++
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/Castle.Facilities.WcfIntegration.Tests-vs2008.csproj
2009-12-05 15:50:04 UTC (rev 6392)
@@ -123,8 +123,15 @@
<Compile Include="Components\ICalculator.cs" />
<Compile Include="Components\TraceInterceptor.cs" />
<Compile Include="Duplex\DuplexClientFixture.cs" />
+ <Compile Include="Components\IOne.cs" />
+ <Compile Include="Components\IServiceWithSession.cs" />
+ <Compile Include="Components\ITwo.cs" />
+ <Compile Include="Components\One.cs" />
+ <Compile Include="PerWcfSessionLifestyleTestCase.cs" />
<Compile Include="Rest\RestClientFixture.cs" />
<Compile Include="Rest\RestServiceFixture.cs" />
+ <Compile Include="Components\ServiceWithSession.cs" />
+ <Compile Include="Components\Two.cs" />
<Compile Include="WcfClientFixture.cs" />
<Compile Include="Components\IOperations.cs" />
Directory:
/Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/Client/Proxy/
===================================================================================
File [modified]: WcfProxyGenerationHook.cs
Delta lines: +9 -0
===================================================================
---
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/Lifestyles/IOperationContextProvider.cs
(rev 0)
+++
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/Lifestyles/IOperationContextProvider.cs
2009-12-05 15:50:04 UTC (rev 6392)
@@ -0,0 +1,9 @@
+namespace Castle.Facilities.WcfIntegration.Lifestyles
+{
+ using System.ServiceModel;
+
+ public interface IOperationContextProvider
+ {
+ OperationContext Current { get; }
+ }
+}
--
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.