User: xtoff
Date: 2009/12/31 04:29 PM

Added:
 /Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/
  CollectingInterceptor.cs, PerWcfOperationLifestyleTestCase.cs
 /Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/Components/
  HasOne.cs, IServiceWithDependencies.cs, ServiceWithDependencies.cs
 /Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/Lifestyles/
  AbstractWcfLifestyleCache.cs, AbstractWcfLifestyleManager.cs, 
IWcfLifestyle.cs, IWcfLifestyleCache.cs, PerChannelCache.cs, 
PerOperationCache.cs, PerWcfOperationLifestyle.cs

Modified:
 /Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/
  Castle.Facilities.WcfIntegration.Tests-vs2008.csproj, 
PerWcfSessionLifestyleTestCase.cs
 /Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/
  Castle.Facilities.WcfIntegration-vs2008.csproj
 /Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/Lifestyles/
  LifestyleRegistrationExtensions.cs, PerWcfSessionLifestyle.cs

Log:
 - added per wcf operation (context) lifestyle.
 HAPPY NEW YEAR!

File Changes:

Directory: /Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/
======================================================================

File [modified]: Castle.Facilities.WcfIntegration-vs2008.csproj
Delta lines: +103 -0
===================================================================

--- 
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/Lifestyles/AbstractWcfLifestyleCache.cs
                           (rev 0)
+++ 
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/Lifestyles/AbstractWcfLifestyleCache.cs
   2009-12-31 23:29:57 UTC (rev 6550)
@@ -0,0 +1,103 @@
+// 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.Lifestyles
+{
+       using System;
+       using System.Collections.Generic;
+       using System.ServiceModel;
+
+       public abstract class AbstractWcfLifestyleCache<TContext> : 
IWcfLifestyleCache<TContext>
+               where TContext : class, IExtensibleObject<TContext>
+       {
+               private readonly IDictionary<IWcfLifestyle, object> components 
= new Dictionary<IWcfLifestyle, object>(new WcfLifestyleComparer());
+               private TContext channel;
+               private bool used;
+
+               public object this[IWcfLifestyle manager]
+               {
+                       get
+                       {
+                               object component;
+                               components.TryGetValue(manager, out component);
+                               return component;
+                       }
+                       set
+                       {
+                               components[manager] = value;
+                       }
+               }
+
+               public void Attach(TContext 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;
+                       InitContext(channel);
+               }
+
+               public void Detach(TContext owner)
+               {
+                       if (!used)
+                       {
+                               throw new InvalidOperationException("This 
instance was not used!");
+                       }
+
+                       if (channel == null)
+                       {
+                               throw new InvalidOperationException("Can't 
Detach twice or before attaching!");
+                       }
+
+                       ShutdownContext(channel);
+                       channel = null;
+               }
+
+               protected void ShutdownCache()
+               {
+                       channel.Extensions.Remove(this);
+                       foreach (var component in components)
+                       {
+                               component.Key.Release(component.Value);
+                       }
+
+                       components.Clear();
+               }
+
+               protected abstract void ShutdownContext(TContext context);
+
+               protected abstract void InitContext(TContext context);
+
+               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();
+                       }
+               }
+       }
+}

Directory: /Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/
============================================================================

File [modified]: Castle.Facilities.WcfIntegration.Tests-vs2008.csproj
Delta lines: +35 -0
===================================================================

--- 
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/CollectingInterceptor.cs
                            (rev 0)
+++ 
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/CollectingInterceptor.cs
    2009-12-31 23:29:57 UTC (rev 6550)
@@ -0,0 +1,35 @@
+// 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.Collections.Generic;
+
+       using Castle.Core.Interceptor;
+
+       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);
+               }
+       }
+}

File [added]: CollectingInterceptor.cs
Delta lines: +26 -0
===================================================================

--- 
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/Components/HasOne.cs
                                (rev 0)
+++ 
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/Components/HasOne.cs
        2009-12-31 23:29:57 UTC (rev 6550)
@@ -0,0 +1,26 @@
+// 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 HasOne
+       {
+               public IOne One { get; set; }
+
+               public HasOne(IOne one)
+               {
+                       One = one;
+               }
+       }
+}

File [added]: PerWcfOperationLifestyleTestCase.cs
Delta lines: +0 -17
===================================================================

--- 
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/PerWcfSessionLifestyleTestCase.cs
   2009-12-31 02:45:49 UTC (rev 6549)
+++ 
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/PerWcfSessionLifestyleTestCase.cs
   2009-12-31 23:29:57 UTC (rev 6550)
@@ -15,13 +15,11 @@
 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;
@@ -142,19 +140,4 @@
                        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);
-               }
-       }
 }

File [modified]: PerWcfSessionLifestyleTestCase.cs
Delta lines: +0 -0
===================================================================

Directory: 
/Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/Components/
=======================================================================================

File [added]: HasOne.cs
Delta lines: +25 -0
===================================================================

--- 
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/Components/IServiceWithDependencies.cs
                              (rev 0)
+++ 
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/Components/IServiceWithDependencies.cs
      2009-12-31 23:29:57 UTC (rev 6550)
@@ -0,0 +1,25 @@
+// 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]
+       public interface IServiceWithDependencies
+       {
+               [OperationContract]
+               void OperationOne();
+       }
+}

File [added]: IServiceWithDependencies.cs
Delta lines: +39 -0
===================================================================

--- 
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/Components/ServiceWithDependencies.cs
                               (rev 0)
+++ 
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/Components/ServiceWithDependencies.cs
       2009-12-31 23:29:57 UTC (rev 6550)
@@ -0,0 +1,39 @@
+// 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.Collections.Generic;
+       using System.ServiceModel;
+
+       [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
+       public class ServiceWithDependencies : IServiceWithDependencies
+       {
+               private readonly IOne one;
+               private readonly HasOne hasOne;
+               public static readonly IList<object> Dependencies = new 
List<object>();
+
+               public ServiceWithDependencies(IOne one,HasOne hasOne)
+               {
+                       this.one = one;
+                       this.hasOne = hasOne;
+               }
+
+               public void OperationOne()
+               {
+                       Dependencies.Add(one);
+                       Dependencies.Add(hasOne);
+               }
+       }
+}

File [added]: ServiceWithDependencies.cs
Delta lines: +90 -0
===================================================================

--- 
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/PerWcfOperationLifestyleTestCase.cs
                         (rev 0)
+++ 
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/PerWcfOperationLifestyleTestCase.cs
 2009-12-31 23:29:57 UTC (rev 6550)
@@ -0,0 +1,90 @@
+// 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.ServiceModel;
+
+       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 PerWcfOperationLifestyleTestCase
+       {
+               [SetUp]
+               public void SetUp()
+               {
+                       windsorContainer = new WindsorContainer()
+                               .AddFacility<WcfFacility>(f => f.CloseTimeout = 
TimeSpan.Zero)
+                               .Register(
+                               Component.For<ServiceHostListener>(),
+                               Component.For<UnitOfworkEndPointBehavior>(),
+                               Component.For<NetDataContractFormatBehavior>(),
+                               
Component.For<IOne>().ImplementedBy<One>().LifeStyle.PerWcfOperation(),
+                               
Component.For<HasOne>().LifeStyle.PerWcfOperation(),
+                               
Component.For<IServiceWithDependencies>().ImplementedBy<ServiceWithDependencies>().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();
+                       ServiceWithDependencies.Dependencies.Clear();
+               }
+
+               private IWindsorContainer windsorContainer;
+               private IServiceWithDependencies client;
+
+               private IServiceWithDependencies CreateClient()
+               {
+                       return 
ChannelFactory<IServiceWithDependencies>.CreateChannel(
+                               new NetTcpBinding { PortSharingEnabled = true 
}, new EndpointAddress("net.tcp://localhost/Operations"));
+               }
+
+               [Test]
+               public void 
Dependencies_should_be_reused_among_services_within_call()
+               {
+                       client.OperationOne();
+                       Assert.AreEqual(2, 
ServiceWithDependencies.Dependencies.Count);
+                       var one = ServiceWithDependencies.Dependencies[0] as 
IOne;
+                       var hasOne = ServiceWithDependencies.Dependencies[1] as 
HasOne;
+                       Assert.AreSame(one, hasOne.One);
+               }
+
+               [Test]
+               public void Dependencies_should_not_reused_among_between_calls()
+               {
+                       client.OperationOne();
+                       client.OperationOne();
+                       Assert.AreEqual(4, 
ServiceWithDependencies.Dependencies.Count);
+                       var one1 = ServiceWithDependencies.Dependencies[0] as 
IOne;
+                       var one2 = ServiceWithDependencies.Dependencies[2] as 
IOne;
+                       Assert.AreNotSame(one1, one2);
+               }
+       }
+}

Directory: 
/Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/Lifestyles/
=================================================================================

File [added]: AbstractWcfLifestyleCache.cs
Delta lines: +67 -0
===================================================================

--- 
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/Lifestyles/AbstractWcfLifestyleManager.cs
                         (rev 0)
+++ 
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/Lifestyles/AbstractWcfLifestyleManager.cs
 2009-12-31 23:29:57 UTC (rev 6550)
@@ -0,0 +1,67 @@
+// 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.Lifestyles
+{
+       using System;
+       using System.ServiceModel;
+
+       using Castle.MicroKernel;
+       using Castle.MicroKernel.Lifestyle;
+
+       public abstract class AbstractWcfLifestyleManager<TExtensibleObject, 
TCache> : AbstractLifestyleManager, IWcfLifestyle
+               where TExtensibleObject : class, 
IExtensibleObject<TExtensibleObject>
+               where TCache : class, IWcfLifestyleCache<TExtensibleObject>, 
new()
+       {
+
+               private readonly Guid id = Guid.NewGuid();
+
+               public Guid ComponentId
+               {
+                       get { return id; }
+               }
+
+               public override void Dispose()
+               {
+
+               }
+
+               public override object Resolve(CreationContext context)
+               {
+                       var cacheHolder = GetCacheHolder();
+                       if (cacheHolder == null)
+                       {
+                               return base.Resolve(context);
+                       }
+
+                       var cache = cacheHolder.Extensions.Find<TCache>();
+                       if (cache == null)
+                       {
+                               cache = new TCache();
+                               cacheHolder.Extensions.Add(cache);
+                       }
+
+                       var component = cache[this];
+                       if (component == null)
+                       {
+                               component = base.Resolve(context);
+                               cache[this] = component;
+                       }
+
+                       return component;
+               }
+
+               protected abstract TExtensibleObject GetCacheHolder();
+       }
+}

File [added]: AbstractWcfLifestyleManager.cs
Delta lines: +25 -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-31 23:29:57 UTC (rev 6550)
@@ -0,0 +1,25 @@
+// 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.Lifestyles
+{
+       using System;
+
+       using Castle.MicroKernel;
+
+       public interface IWcfLifestyle : ILifestyleManager
+       {
+               Guid ComponentId { get; }
+       }
+}

File [added]: IWcfLifestyle.cs
Delta lines: +24 -0
===================================================================

--- 
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/Lifestyles/IWcfLifestyleCache.cs
                          (rev 0)
+++ 
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/Lifestyles/IWcfLifestyleCache.cs
  2009-12-31 23:29:57 UTC (rev 6550)
@@ -0,0 +1,24 @@
+// 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.Lifestyles
+{
+       using System.ServiceModel;
+
+       public interface IWcfLifestyleCache<TContext> : IExtension<TContext>
+               where TContext : class, IExtensibleObject<TContext>
+       {
+               object this[IWcfLifestyle manager] { get; set; }
+       }
+}

File [added]: IWcfLifestyleCache.cs
Delta lines: +11 -5
===================================================================

--- 
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/Lifestyles/LifestyleRegistrationExtensions.cs
     2009-12-31 02:45:49 UTC (rev 6549)
+++ 
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/Lifestyles/LifestyleRegistrationExtensions.cs
     2009-12-31 23:29:57 UTC (rev 6550)
@@ -1,13 +1,19 @@
-namespace Castle.Facilities.WcfIntegration.Lifestyles
+namespace Castle.Facilities.WcfIntegration
 {
+       using 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>();
-                }
+               public static ComponentRegistration<S> PerWcfSession<S>(this 
LifestyleGroup<S> @group)
+               {
+                       return group.Custom<PerWcfSessionLifestyle>();
+               }
+
+               public static ComponentRegistration<S> PerWcfOperation<S>(this 
LifestyleGroup<S> @group)
+               {
+                       return group.Custom<PerWcfOperationLifestyle>();
+               }
        }
 }

File [modified]: LifestyleRegistrationExtensions.cs
Delta lines: +25 -0
===================================================================

--- 
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/Lifestyles/PerChannelCache.cs
                             (rev 0)
+++ 
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/Lifestyles/PerChannelCache.cs
     2009-12-31 23:29:57 UTC (rev 6550)
@@ -0,0 +1,25 @@
+namespace Castle.Facilities.WcfIntegration.Lifestyles
+{
+       using System;
+       using System.ServiceModel;
+
+       public class PerChannelCache : 
AbstractWcfLifestyleCache<IContextChannel>
+       {
+               protected override void InitContext(IContextChannel context)
+               {
+                       context.Faulted += Shutdown;
+                       context.Closed += Shutdown;
+               }
+
+               protected override void ShutdownContext(IContextChannel context)
+               {
+                       context.Faulted -= Shutdown;
+                       context.Closed -= Shutdown;
+               }
+
+               private void Shutdown(object sender, EventArgs e)
+               {
+                       ShutdownCache();
+               }
+       }
+}

File [added]: PerChannelCache.cs
Delta lines: +37 -0
===================================================================

--- 
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/Lifestyles/PerOperationCache.cs
                           (rev 0)
+++ 
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/Lifestyles/PerOperationCache.cs
   2009-12-31 23:29:57 UTC (rev 6550)
@@ -0,0 +1,37 @@
+// 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.Lifestyles
+{
+       using System;
+       using System.ServiceModel;
+
+       public class PerOperationCache : 
AbstractWcfLifestyleCache<OperationContext>
+       {
+               protected override void InitContext(OperationContext context)
+               {
+                       context.OperationCompleted += Shutdown;
+               }
+
+               protected override void ShutdownContext(OperationContext 
context)
+               {
+                       context.OperationCompleted -= Shutdown;
+               }
+
+               private void Shutdown(object sender, EventArgs e)
+               {
+                       ShutdownCache();
+               }
+       }
+}

File [added]: PerOperationCache.cs
Delta lines: +49 -0
===================================================================

--- 
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/Lifestyles/PerWcfOperationLifestyle.cs
                            (rev 0)
+++ 
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/Lifestyles/PerWcfOperationLifestyle.cs
    2009-12-31 23:29:57 UTC (rev 6550)
@@ -0,0 +1,49 @@
+// 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.Lifestyles
+{
+       using System;
+       using System.ServiceModel;
+
+       /// <summary>
+       /// Manages object instances in the context of WCF operation. This 
means that when a component 
+       /// with this lifestyle is requested multiple times during WCF 
operation, the same instance will be provided.
+       /// If no WCF operation is available falls back to the default behavior 
of transient.
+       /// </summary>
+       public class PerWcfOperationLifestyle : 
AbstractWcfLifestyleManager<OperationContext, PerOperationCache>
+       {
+               private readonly IOperationContextProvider contextProvider;
+
+               public PerWcfOperationLifestyle()
+                       : this(new OperationContextProvider())
+               {
+               }
+
+               public PerWcfOperationLifestyle(IOperationContextProvider 
contextProvider)
+               {
+                       if (contextProvider == null)
+                       {
+                               throw new 
ArgumentNullException("contextProvider");
+                       }
+
+                       this.contextProvider = contextProvider;
+               }
+
+               protected override OperationContext GetCacheHolder()
+               {
+                       return contextProvider.Current;
+               }
+       }
+}

File [added]: PerWcfOperationLifestyle.cs
Delta lines: +8 -28
===================================================================

--- 
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/Lifestyles/PerWcfSessionLifestyle.cs
      2009-12-31 02:45:49 UTC (rev 6549)
+++ 
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration/Lifestyles/PerWcfSessionLifestyle.cs
      2009-12-31 23:29:57 UTC (rev 6550)
@@ -1,16 +1,14 @@
 namespace Castle.Facilities.WcfIntegration.Lifestyles
 {
        using System;
+       using System.ServiceModel;
 
-       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
+       public class PerWcfSessionLifestyle : 
AbstractWcfLifestyleManager<IContextChannel, PerChannelCache>
        {
                private readonly IOperationContextProvider 
operationContextProvider;
 
@@ -29,38 +27,20 @@
                        this.operationContextProvider = 
operationContextProvider;
                }
 
-               public override void Dispose()
+               protected override IContextChannel GetCacheHolder()
                {
-
-               }
-
-               public override object Resolve(CreationContext context)
-               {
                        var operation = operationContextProvider.Current;
-                       if (operation == null || 
string.IsNullOrEmpty(operation.SessionId))
+                       if (operation == null)
                        {
-                               return base.Resolve(context);
+                               return null;
                        }
 
-                       var channel = operation.Channel;
-
-                       // TODO: does this need locking?
-                       var lifestyle = 
channel.Extensions.Find<PerChannelLifestyleExtension>();
-
-                       if (lifestyle == null)
+                       if (string.IsNullOrEmpty(operation.SessionId))
                        {
-                               lifestyle = new PerChannelLifestyleExtension();
-                               channel.Extensions.Add(lifestyle);
+                               return null;
                        }
 
-                       var component = lifestyle[this];
-                       if (component == null)
-                       {
-                               component = base.Resolve(context);
-                               lifestyle[this] = component;
-                       }
-
-                       return component;
+                       return operation.Channel;
                }
        }
 }

File [modified]: PerWcfSessionLifestyle.cs
Delta lines: +5 -0
===================================================================

--- 
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/Castle.Facilities.WcfIntegration.Tests-vs2008.csproj
        2009-12-31 02:45:49 UTC (rev 6549)
+++ 
Facilities/Wcf/trunk/src/Castle.Facilities.WcfIntegration.Tests/Castle.Facilities.WcfIntegration.Tests-vs2008.csproj
        2009-12-31 23:29:57 UTC (rev 6550)
@@ -115,18 +115,23 @@
     <Compile Include="Behaviors\ReplaceOperationsResult.cs" />
     <Compile Include="Behaviors\ServiceHostListener.cs" />
     <Compile Include="Behaviors\UnitOfworkEndPointBehavior.cs" />
+    <Compile Include="CollectingInterceptor.cs" />
     <Compile Include="Components\Calculator.cs" />
     <Compile Include="Components\Callback.cs" />
     <Compile Include="Components\ClassNeedingService.cs" />
+    <Compile Include="Components\HasOne.cs" />
     <Compile Include="Components\Inventory.cs" />
     <Compile Include="Components\HelloFormatter.cs" />
     <Compile Include="Components\ICalculator.cs" />
+    <Compile Include="Components\IServiceWithDependencies.cs" />
+    <Compile Include="Components\ServiceWithDependencies.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="PerWcfOperationLifestyleTestCase.cs" />
     <Compile Include="PerWcfSessionLifestyleTestCase.cs" />
     <Compile Include="Rest\RestClientFixture.cs" />

--

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.


Reply via email to