ProxyFactoryObjectTests.cs :  » Inversion-of-Control-Dependency-Injection » Spring.net » Spring » Aop » Framework » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Inversion of Control Dependency Injection » Spring.net 
Spring.net » Spring » Aop » Framework » ProxyFactoryObjectTests.cs
#region License

/*
 * Copyright  2002-2005 the original author or authors.
 *
 * 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.
 */

#endregion

#region Imports

using System;
using System.IO;
using System.Security.Policy;
using System.Collections;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Web;

using AopAlliance.Aop;
using AopAlliance.Intercept;
using NUnit.Framework;
using Rhino.Mocks;
using Spring.Aop.Advice;
using Spring.Aop.Framework.Adapter;
using Spring.Aop.Interceptor;
using Spring.Aop.Support;
using Spring.Aop.Target;
using Spring.Context;
using Spring.Core.IO;
using Spring.Objects;
using Spring.Objects.Factory;
using Spring.Objects.Factory.Support;
using Spring.Objects.Factory.Xml;
using Spring.Proxy;
using Spring.Threading;

#endregion

namespace Spring.Aop.Framework{
    /// <summary>
    /// Integration test cases for the ProxyFactoryObject, using an XML object factory.
    /// </summary>
    /// <author>Rod Johnson</author>
    /// <author>Federico Spinazzi (.NET)</author>
    /// <author>Choy Rim (.NET)</author>
    /// <author>Aleksandar Seovic (.NET)</author>
    [TestFixture]
    public sealed class ProxyFactoryObjectTests
    {
        private MockRepository mocks;
        private IObjectFactory factory;

        [SetUp]
        public void SetUp()
        {
            mocks = new MockRepository();
            factory = new XmlObjectFactory(new ReadOnlyXmlTestResource("proxyFactoryTests.xml", GetType()));
        }


        [Test]
        public void TargetThrowsInvalidCastException()
        {
            Exception expectedException = new InvalidCastException();
            ITestObject test1 = (ITestObject)factory.GetObject("test1");
            try
            {
                test1.Exceptional(expectedException);
                Assert.Fail("Should have thrown exception raised by target");
            }
            catch (Exception ex)
            {
                Assert.AreEqual(expectedException, ex, "exception matches");
                Assert.AreEqual(1, test1.ExceptionMethodCallCount);
            }
        }

        [Test]
        public void IsCompositionProxy()
        {
            ITestObject test1 = (ITestObject)factory.GetObject("test1");
            Assert.IsTrue(AopUtils.IsCompositionAopProxy(test1), "test1 is a composition proxy");
        }

        [Test]
        public void GetObjectTypeWithDirectTarget()
        {
            IObjectFactory bf = new XmlObjectFactory(
                new ReadOnlyXmlTestResource("proxyFactoryTargetSourceTests.xml",
                                            GetType()));

            // We have a counting before advice here
            CountingBeforeAdvice cba = (CountingBeforeAdvice)bf.GetObject("countingBeforeAdvice");
            Assert.AreEqual(0, cba.GetCalls());

            ITestObject tb = (ITestObject)bf.GetObject("directTarget");
            Assert.IsTrue(tb.Name.Equals("Adam"));
            Assert.AreEqual(1, cba.GetCalls());

            ProxyFactoryObject pfb = (ProxyFactoryObject)bf.GetObject("&directTarget");
            Assert.IsTrue(typeof(ITestObject).IsAssignableFrom(pfb.ObjectType), "Has correct object type");
        }

        [Test]
        public void GetObjectTypeWithTargetViaTargetSource()
        {
            IObjectFactory bf = new XmlObjectFactory(
                new ReadOnlyXmlTestResource("proxyFactoryTargetSourceTests.xml",
                                            GetType()));
            ITestObject tb = (ITestObject)bf.GetObject("viaTargetSource");
            Assert.IsTrue(tb.Name.Equals("Adam"));
            ProxyFactoryObject pfb = (ProxyFactoryObject)bf.GetObject("&viaTargetSource");
            Assert.IsTrue(typeof(ITestObject).IsAssignableFrom(pfb.ObjectType), "Has correct object type");
        }

        [Test]
        public void GetObjectTypeWithNoTargetOrTargetSource()
        {
            IObjectFactory bf =
        new XmlObjectFactory(new ReadOnlyXmlTestResource("proxyFactoryTargetSourceTests.xml", GetType()));
            bf.GetObject("noTarget");
            IFactoryObject pfb = (ProxyFactoryObject)bf.GetObject("&noTarget");
            Assert.IsTrue(typeof(ITestObject).IsAssignableFrom(pfb.ObjectType), "Has correct object type");
        }

        /// <summary>
        /// The instances are equal, but do not have object identity.
        /// Interceptors and interfaces and the target are the same.
        /// </summary>
        [Test]
        public void SingletonInstancesAreEqual()
        {
            ITestObject test1 = (ITestObject)factory.GetObject("test1");
            ITestObject test1_1 = (ITestObject)factory.GetObject("test1");
            Assert.AreEqual(test1, test1_1, "Singleton instances ==");
            test1.Age = 25;
            Assert.AreEqual(test1.Age, test1_1.Age);
            test1.Age = 250;
            Assert.AreEqual(test1.Age, test1_1.Age);
            IAdvised pc1 = (IAdvised)test1;
            IAdvised pc2 = (IAdvised)test1_1;
            Assert.AreEqual(pc1.Advisors, pc2.Advisors);
            int oldLength = pc1.Advisors.Length;
            NopInterceptor di = new NopInterceptor();
            pc1.AddAdvice(1, di);
            Assert.AreEqual(pc1.Advisors, pc2.Advisors);
            Assert.AreEqual(oldLength + 1, pc2.Advisors.Length, "Now have one more advisor");
            Assert.AreEqual(di.Count, 0);
            test1.Age = (5);
            Assert.AreEqual(test1_1.Age, test1.Age);
            Assert.AreEqual(3, di.Count);
        }

        [Test]
        public void PrototypeInstancesAreNotEqual()
        {
            ITestObject test2 = (ITestObject)factory.GetObject("prototype");
            ITestObject test2_1 = (ITestObject)factory.GetObject("prototype");
            Assert.IsTrue(test2 != test2_1, "Prototype instances !=");
            Assert.IsTrue(TestObject.Equals(test2, test2_1), "Prototype instances equal");
        }

        [Test]
        public void PrototypeInstancesAreIndependent()
        {
            IObjectFactory objectFactory = new XmlObjectFactory(new ReadOnlyXmlTestResource("prototypeTests.xml", GetType()));
            // Initial count value set in object factory XML
            int INITIAL_COUNT = 10;


            // Check it works without AOP
            ISideEffectObject raw = (ISideEffectObject)objectFactory.GetObject("prototypeTarget");
            Assert.AreEqual(INITIAL_COUNT, raw.Count);
            raw.doWork();
            Assert.AreEqual(INITIAL_COUNT + 1, raw.Count);
            raw = (ISideEffectObject)objectFactory.GetObject("prototypeTarget");
            Assert.AreEqual(INITIAL_COUNT, raw.Count);

            // Now try with advised instances
            ISideEffectObject prototype2FirstInstance = (ISideEffectObject)objectFactory.GetObject("prototype");
            Assert.AreEqual(INITIAL_COUNT, prototype2FirstInstance.Count);
            prototype2FirstInstance.doWork();
            Assert.AreEqual(INITIAL_COUNT + 1, prototype2FirstInstance.Count);

            ISideEffectObject prototype2SecondInstance = (ISideEffectObject)objectFactory.GetObject("prototype");
            Assert.IsFalse(prototype2FirstInstance == prototype2SecondInstance, "Prototypes are not ==");
            Assert.AreEqual(INITIAL_COUNT, prototype2SecondInstance.Count);
            Assert.AreEqual(INITIAL_COUNT + 1, prototype2FirstInstance.Count);


        }


        /// <summary> Test invoker is automatically added to manipulate target</summary>
        [Test]
        public void AutoInvoker()
        {
            String name = "Hieronymous";
            TestObject target = (TestObject)factory.GetObject("test");
            target.Name = name;
            ITestObject autoInvoker = (ITestObject)factory.GetObject("autoInvoker");
            Assert.IsTrue(autoInvoker.Name.Equals(name));
        }

        [Test]
        public void CanGetFactoryReferenceAndManipulate()
        {
            ITestObject to = (ITestObject)factory.GetObject("test1");
            // no exception
            string dummy = to.Name;

            IAdvised config = (IAdvised)to;
            Assert.AreEqual(1, config.Advisors.Length, "Object should have only one advisors");

            Exception ex = new NotSupportedException("Invoke");
            // Add evil interceptor to head of list
            config.AddAdvice(0, new EvilMethodInterceptor(ex));
            Assert.AreEqual(2, config.Advisors.Length, "The advisor count is wrong after adding an advisor programmatically.");

            try
            {
                // evil interceptor should throw exception
                dummy = to.Name;
                Assert.Fail("Evil interceptor added programmatically should fail all method calls, but it didn't");
            }
            catch (Exception thrown)
            {
                Assert.AreEqual(thrown, ex, "The thrown exception is not the one we were looking for.");
            }
        }

        /// <summary>
        /// Must see effect immediately on behaviour.
        /// TODO (EE): Note that we can't add or remove interfaces without reconfiguring the singleton.
        /// </summary>
        [Test, Ignore("change according to ProxyFactoryBeanTests.canAddAndRemoveAdvicesOnSingleton")]
        public void CanAddAndRemoveIntroductionsOnSingleton()
        {
            try
            {
                ITimeStamped ts = (ITimeStamped)factory.GetObject("test1");
                Assert.Fail("Shouldn't implement ITimeStamped before manipulation");
            }
            catch (InvalidCastException)
            {
            }

            ProxyFactoryObject config = (ProxyFactoryObject)factory.GetObject("&test1");
            long time = 666L;
            TimestampIntroductionInterceptor ti = new TimestampIntroductionInterceptor();
            ti.TimeStamp = new DateTime(time);
            IIntroductionAdvisor advisor = new DefaultIntroductionAdvisor(ti, typeof(ITimeStamped));

            // add to front of introduction chain
            int oldCount = config.Introductions.Length;
            config.AddIntroduction(0, advisor);
            Assert.IsTrue(config.Introductions.Length == oldCount + 1);

            ITimeStamped ts2 = (ITimeStamped)factory.GetObject("test1");
            Assert.IsTrue(ts2.TimeStamp == new DateTime(time));

            // Can remove
            config.RemoveIntroduction(advisor);
            Assert.IsTrue(config.Introductions.Length == oldCount);

            // Existing reference will still work
            object o = ts2.TimeStamp;

            // But new proxies should not implement ITimeStamped
            try
            {
                ts2 = (ITimeStamped)factory.GetObject("test1");
                Assert.Fail("Should no longer implement ITimeStamped");
            }
            catch (InvalidCastException)
            {
                // expected...
            }

            // Now check non-effect of removing interceptor that isn't there
            oldCount = config.Advisors.Length;
            config.RemoveAdvice(new DebugAdvice());
            Assert.IsTrue(config.Advisors.Length == oldCount);

            ITestObject it = (ITestObject)ts2;
            DebugAdvice debugInterceptor = new DebugAdvice();
            config.AddAdvice(0, debugInterceptor);
            object foo = it.Spouse;
            Assert.AreEqual(1, debugInterceptor.Count);
            config.RemoveAdvice(debugInterceptor);
            foo = it.Spouse;
            // not invoked again
            Assert.IsTrue(debugInterceptor.Count == 1);
        }

        /// <summary> Try adding and removing interfaces and interceptors on prototype.
        /// Changes will only affect future references obtained from the factory.
        /// Each instance will be independent.
        /// </summary>
        [Test]
        public void CanAddAndRemoveAspectInterfacesOnPrototype()
        {
            try
            {
                ITimeStamped ts = (ITimeStamped)factory.GetObject("test2");
                Assert.Fail("Shouldn't implement ITimeStamped before manipulation");
            }
            catch (InvalidCastException)
            {
            }

            IAdvised config = (IAdvised)factory.GetObject("&test2");
            long time = 666L;
            TimestampIntroductionInterceptor ti = new TimestampIntroductionInterceptor();
            ti.TimeStamp = new DateTime(time);
            IIntroductionAdvisor advisor = new DefaultIntroductionAdvisor(ti, typeof(ITimeStamped));

            // add to front of introduction chain
            int oldCount = config.Introductions.Length;
            config.AddIntroduction(0, advisor);
            Assert.IsTrue(config.Introductions.Length == oldCount + 1);

            ITimeStamped ts2 = (ITimeStamped)factory.GetObject("test2");
            Assert.IsTrue(ts2.TimeStamp == new DateTime(time));

            // Can remove
            config.RemoveIntroduction(advisor);
            Assert.IsTrue(config.Introductions.Length == oldCount);

            // Existing reference will still work
            object o = ts2.TimeStamp;

            // But new proxies should not implement ITimeStamped
            try
            {
                ts2 = (ITimeStamped)factory.GetObject("test2");
                Assert.Fail("Should no longer implement ITimeStamped");
            }
            catch (InvalidCastException)
            {
            }

            // Now check non-effect of removing interceptor that isn't there
            ITestObject it = (ITestObject)factory.GetObject("test2");
            config = (IAdvised)it;

            oldCount = config.Advisors.Length;
            config.RemoveAdvice(new DebugAdvice());
            Assert.IsTrue(config.Advisors.Length == oldCount);

            DebugAdvice debugInterceptor = new DebugAdvice();
            config.AddAdvice(0, debugInterceptor);
            object foo = it.Spouse;
            Assert.AreEqual(1, debugInterceptor.Count);
            config.RemoveAdvice(debugInterceptor);
            foo = it.Spouse;
            // not invoked again
            Assert.IsTrue(debugInterceptor.Count == 1);
        }

        /// <summary>
        /// Note that we can't add or remove interfaces without reconfiguring the
        /// singleton.
        /// </summary>
        [Test]
        public void CanAddAndRemoveAspectInterfacesOnSingletonByCasting()
        {
            ITestObject it = (ITestObject)factory.GetObject("test1");
            IAdvised pc = (IAdvised)it;
            object name = it.Age;
            NopInterceptor di = new NopInterceptor();
            pc.AddAdvice(0, di);
            Assert.AreEqual(0, di.Count);
            it.Age = 25;
            Assert.AreEqual(25, it.Age);
            Assert.AreEqual(2, di.Count);
        }

        [Test]
        public void MethodPointcuts()
        {
            ITestObject tb = (ITestObject)factory.GetObject("pointcuts");
            PointcutForVoid.Reset();
            Assert.IsTrue((PointcutForVoid.methodNames.Count == 0), "No methods intercepted");
            object o = tb.Age;
            Assert.IsTrue((PointcutForVoid.methodNames.Count == 0), "Not void: shouldn't have intercepted");
            tb.Age = 1;
            o = tb.Age;
            tb.Name = "Tristan";
            tb.ToString();
            Assert.AreEqual(2, PointcutForVoid.methodNames.Count, "Recorded wrong number of invocations");
            Assert.AreEqual("set_Age", PointcutForVoid.methodNames[0]);
            Assert.AreEqual("set_Name", PointcutForVoid.methodNames[1]);
        }

        [Test]
        public void CanAddThrowsAdviceWithoutAdvisor()
        {
            IObjectFactory f = new XmlObjectFactory(new ReadOnlyXmlTestResource("throwsAdvice.xml", GetType()));
            ThrowsAdviceInterceptorTests.MyThrowsHandler th =
                (ThrowsAdviceInterceptorTests.MyThrowsHandler)f.GetObject("throwsAdvice");
            CountingBeforeAdvice cba = (CountingBeforeAdvice)f.GetObject("countingBeforeAdvice");
            Assert.AreEqual(0, cba.GetCalls());
            Assert.AreEqual(0, th.GetCalls());
            ThrowsAdviceInterceptorTests.IEcho echo = (ThrowsAdviceInterceptorTests.IEcho)f.GetObject("throwsAdvised");
            echo.A = 12;
            Assert.AreEqual(1, cba.GetCalls());
            Assert.AreEqual(0, th.GetCalls());
            Exception expected = new Exception();
            try
            {
                echo.EchoException(1, expected);
                Assert.Fail();
            }
            catch (Exception ex)
            {
                Assert.AreEqual(expected, ex);
            }
            // No throws handler method: count should still be 0
            Assert.AreEqual(0, th.GetCalls());

            // Handler knows how to handle this exception
            expected = new HttpException();
            try
            {
                echo.EchoException(1, expected);
                Assert.Fail();
            }
            catch (HttpException ex)
            {
                Assert.AreEqual(expected, ex);
            }
            // One match
            Assert.AreEqual(1, th.GetCalls("HttpException"));
        }

        /// <summary> Checks that globals get invoked,
        /// and that they can add aspect interfaces unavailable
        /// to other objects. These interfaces don't need
        /// to be included in proxiedInterface [].
        /// </summary>
        [Test]
        [ExpectedException(typeof(InvalidCastException))]
        public void GlobalsCanAddAspectInterfaces()
        {
            IAddedGlobalInterface agi = (IAddedGlobalInterface)factory.GetObject("autoInvoker");
            Assert.IsTrue(agi.GlobalsAdded == -1);

            ProxyFactoryObject pfb = (ProxyFactoryObject)factory.GetObject("&validGlobals");
            pfb.GetObject(); // for creation
            Assert.AreEqual(2, pfb.Advisors.Length, "Proxy should have 1 global and 1 explicit advisor");
            Assert.AreEqual(1, pfb.Introductions.Length, "Proxy should have 1 global introduction");

            agi.GlobalsAdded = ((IAdvised)agi).Introductions.Length;
            Assert.IsTrue(agi.GlobalsAdded == 1);

            IApplicationEventListener l = (IApplicationEventListener)factory.GetObject("validGlobals");
            agi = (IAddedGlobalInterface)l;
            Assert.IsTrue(agi.GlobalsAdded == -1);
            agi = (IAddedGlobalInterface)factory.GetObject("test1");
        }

        [Test]
        public void IsSingletonFalseReturnsNew_ProxyInstance_NotNewProxyTargetSource()
        {
            GoodCommand target = new GoodCommand();
            IObjectFactory mock = (IObjectFactory) mocks.CreateMock(typeof(IObjectFactory));
            Expect.Call(mock.GetObject("singleton")).Return(target).Repeat.Twice();
            mocks.ReplayAll();

            ProxyFactoryObject fac = new ProxyFactoryObject();
            fac.ProxyInterfaces = new string[] { typeof(ICommand).FullName };
            fac.IsSingleton = false;
            fac.TargetName = "singleton";
            fac.ObjectFactory = mock;
            fac.AddAdvice(new NopInterceptor());

            ICommand one = (ICommand)fac.GetObject();
            ICommand two = (ICommand)fac.GetObject();
            Assert.IsFalse(ReferenceEquals(one, two));

            mocks.VerifyAll();
        }

        [Test]
        public void IsSingletonTrueReturnsNew_ProxyInstance_NotNewProxyTargetSource()
        {
            GoodCommand target = new GoodCommand();
            IObjectFactory mock = (IObjectFactory)mocks.CreateMock(typeof(IObjectFactory));
            Expect.Call(mock.GetObject("singleton")).Return(target);
            mocks.ReplayAll();

            ProxyFactoryObject fac = new ProxyFactoryObject();
            fac.ProxyInterfaces = new string[] { typeof(ICommand).FullName };
            fac.IsSingleton = true; // default, just being explicit...
            fac.TargetName = "singleton";
            fac.ObjectFactory = mock;
            fac.AddAdvice(new NopInterceptor());

            ICommand one = (ICommand)fac.GetObject();
            ICommand two = (ICommand)fac.GetObject();
            Assert.IsTrue(ReferenceEquals(one, two));

            mocks.VerifyAll();
        }

        private ProxyFactoryObject CreateFrozenProxyFactory()
        {
            ProxyFactoryObject fac = new ProxyFactoryObject();
            fac.AddInterface(typeof(ITestObject));
            fac.IsFrozen = true;
            fac.AddAdvisor(new PointcutForVoid()); // this is ok, no proxy created yet
            fac.GetObject();
            return fac;
        }

        [Test]
        public void AddAdvisorWhenConfigIsFrozen()
        {
            ProxyFactoryObject fac = CreateFrozenProxyFactory();
            try
            {
                fac.AddAdvisor(new PointcutForVoid()); // not ok
                Assert.Fail("changing a frozen config must throw AopConfigException");
            }
            catch (AopConfigException)
            {}
        }

        [Test]
        [ExpectedException(typeof(AopConfigException))]
        public void RemoveAdvisorWhenConfigIsFrozen()
        {
            ProxyFactoryObject fac = CreateFrozenProxyFactory();
            fac.IsFrozen = true;
            fac.RemoveAdvisor(new PointcutForVoid());
        }

        [Test]
        [ExpectedException(typeof(AopConfigException))]
        public void ReplaceAdvisorWhenConfigIsFrozen()
        {
            ProxyFactoryObject fac = CreateFrozenProxyFactory();
            fac.IsFrozen = true;
            fac.ReplaceAdvisor(new PointcutForVoid(), new PointcutForVoid());
        }

        [Test]
        public void TargetAtEndOfInterceptorList()
        {
            GoodCommand target = new GoodCommand();
            NopInterceptor advice = new NopInterceptor();

            IObjectFactory mock = (IObjectFactory) mocks.CreateMock(typeof(IObjectFactory));
            Expect.Call(mock.GetObject("advice")).Return(advice);
            Expect.Call(mock.GetObject("singleton")).Return(target);
            Expect.Call(mock.GetType("singleton")).Return(typeof(GoodCommand));
            mocks.ReplayAll();

            ProxyFactoryObject fac = new ProxyFactoryObject();
            fac.ProxyInterfaces = new string[] { typeof(ICommand).FullName };
            fac.IsSingleton = true; // default, just being explicit...
            fac.InterceptorNames = new string[] { "advice", "singleton" };
            fac.ObjectFactory = mock;

            ICommand one = (ICommand)fac.GetObject();
            ICommand two = (ICommand)fac.GetObject();
            Assert.IsTrue(ReferenceEquals(one, two));
            one.Execute();
            Assert.AreEqual(1, advice.Count);
            two.Execute();
            Assert.AreEqual(2, advice.Count);

            mocks.VerifyAll();
        }

        [Test]
        public void MakeSurePrototypeTargetIsNotNeedlesslyCreatedDuringInitialization_Unit()
        {
            GoodCommand target = new GoodCommand();
            NopInterceptor advice = new NopInterceptor();

            MockRepository mocks = new MockRepository();
            IObjectFactory factory = (IObjectFactory) mocks.CreateMock(typeof(IObjectFactory));

            ProxyFactoryObject fac = new ProxyFactoryObject();
            fac.ProxyInterfaces = new string[] { typeof(ICommand).FullName };
            fac.IsSingleton = false;
            fac.InterceptorNames = new string[] { "advice", "prototype" };
            fac.ObjectFactory = factory;

//            using (mocks.Record())
            {
                using (mocks.Unordered())
                {
                    Expect.Call(factory.IsSingleton("advice")).Return(true);
                    Expect.Call(factory.GetObject("advice")).Return(advice);
                    Expect.Call(factory.GetType("prototype")).Return(target.GetType());
                    Expect.Call(factory.GetObject("prototype")).Return(target);
                }
            }
            mocks.ReplayAll();

//            using(mocks.Playback())
            {
                fac.GetObject();
            }
            mocks.VerifyAll();
        }

        [Test]
        public void MakeSurePrototypeTargetIsNotNeedlesslyCreatedDuringInitialization_Integration()
        {
            try
            {
                RootObjectDefinition advice = new RootObjectDefinition(typeof(NopInterceptor));
                // prototype target...
                RootObjectDefinition target = new RootObjectDefinition(typeof(InstantiationCountingCommand), false);

                DefaultListableObjectFactory ctx = new DefaultListableObjectFactory();
                ctx.RegisterObjectDefinition("advice", advice);
                ctx.RegisterObjectDefinition("prototype", target);

                ProxyFactoryObject fac = new ProxyFactoryObject();
                fac.ProxyInterfaces = new string[] { typeof(ICommand).FullName };
                fac.IsSingleton = false;
                fac.InterceptorNames = new string[] { "advice", "prototype" };
                fac.ObjectFactory = ctx;

                Assert.AreEqual(0, InstantiationCountingCommand.NumberOfInstantiations,
                                "Prototype target instance is being (needlessly) created during PFO initialization.");
                fac.GetObject();
                Assert.AreEqual(1, InstantiationCountingCommand.NumberOfInstantiations, "Expected 1 inst");
                fac.GetObject();
                Assert.AreEqual(2, InstantiationCountingCommand.NumberOfInstantiations);
            }
            finally
            {
                InstantiationCountingCommand.NumberOfInstantiations = 0;
            }
        }

        [Test]
        public void SingletonProxyWithPrototypeTargetCreatesTargetOnlyOnce()
        {
            try
            {
                RootObjectDefinition advice = new RootObjectDefinition(typeof(NopInterceptor));
                // prototype target...
                RootObjectDefinition target = new RootObjectDefinition(typeof(InstantiationCountingCommand), false);

                DefaultListableObjectFactory ctx = new DefaultListableObjectFactory();
                ctx.RegisterObjectDefinition("advice", advice);
                ctx.RegisterObjectDefinition("prototype", target);

                ProxyFactoryObject fac = new ProxyFactoryObject();
                fac.ProxyInterfaces = new string[] { typeof(ICommand).FullName };
                fac.IsSingleton = true;
                fac.InterceptorNames = new string[] { "advice", "prototype" };
                fac.ObjectFactory = ctx;

                Assert.AreEqual(0, InstantiationCountingCommand.NumberOfInstantiations, "First Call");
                fac.GetObject();
                Assert.AreEqual(1, InstantiationCountingCommand.NumberOfInstantiations, "Second Call");
                fac.GetObject();
                Assert.AreEqual(1, InstantiationCountingCommand.NumberOfInstantiations, "Third Call");
            }

            finally
            {
                InstantiationCountingCommand.NumberOfInstantiations = 0;
            }
        }

        public class InstantiationCountingCommand : ICommand
        {
            private static int numberOfInstantiations = 0;

            public InstantiationCountingCommand()
            {
                ++numberOfInstantiations;
            }

            public static int NumberOfInstantiations
            {
                get { return numberOfInstantiations; }
                set { numberOfInstantiations = value; }
            }

            public void Execute()
            {
            }
        }

        [Test]
        public void NullNameInInterceptorNamesArrayThrowAopConfigException()
        {
            IObjectFactory factory = (IObjectFactory) mocks.CreateMock(typeof(IObjectFactory));

            ProxyFactoryObject fac = new ProxyFactoryObject();
            fac.ProxyInterfaces = new string[] { typeof(ICommand).FullName };
            fac.IsSingleton = false;
            fac.InterceptorNames = new string[] { null, null };
            fac.ObjectFactory = factory;
            try
            {
                fac.GetObject();
                Assert.Fail();
            }
            catch (AopConfigException)
            {}
        }

        [Test]
        public void PassEmptyInterceptorNamesArray_WithTargetThatImplementsAnInterfaceCanBeCastToSaidInterface()
        {
            IObjectFactory factory = (IObjectFactory) mocks.CreateMock(typeof(IObjectFactory));

            ProxyFactoryObject fac = new ProxyFactoryObject();
            fac.ProxyInterfaces = new string[] { };
            fac.Target = new GoodCommand();
            fac.ObjectFactory = factory;

            IAdvised advised = fac.GetObject() as IAdvised;
            Assert.IsNotNull(advised);

            ICommand cmd = fac.GetObject() as ICommand;
            Assert.IsNotNull(cmd);

            DoesntImplementAnyInterfaces obj = fac.GetObject() as DoesntImplementAnyInterfaces;
            Assert.IsNull(obj);
        }

        [Test]
        [ExpectedException(typeof(AopConfigException))]
        public void PassNullToTheProxyInterfacesProperty()
        {
            ProxyFactoryObject fac = new ProxyFactoryObject();
            fac.ProxyInterfaces = null;
        }

        [Test]
        [ExpectedException(typeof(AopConfigException))]
        public void PassClassNotInterfaceNameToTheProxyInterfacesProperty()
        {
            ProxyFactoryObject fac = new ProxyFactoryObject();
            fac.ProxyInterfaces = new string[] { typeof(GoodCommand).FullName };
        }

        [Test]
        [ExpectedException(typeof(AopConfigException))]
        public void PassRubbishNameToTheProxyInterfacesProperty()
        {
            ProxyFactoryObject fac = new ProxyFactoryObject();
            fac.ProxyInterfaces = new string[] { "Hey" };
        }

        [Test]
        [ExpectedException(typeof(AopConfigException))]
        public void PassNullElementListToTheProxyInterfacesProperty()
        {
            ProxyFactoryObject fac = new ProxyFactoryObject();
            fac.ProxyInterfaces = new string[] { null };
        }

        [Test]
        public void ProxiedObjectUnwrapsTargetInvocationException()
        {
            ProxyFactoryObject fac = new ProxyFactoryObject();
            fac.AddInterface(typeof(ICommand));
            fac.AddAdvice(new NopInterceptor());
            fac.Target = new BadCommand();

            ICommand cmd = (ICommand)fac.GetObject();
            try
            {
                cmd.Execute();
            }
            catch (NotImplementedException)
            {
                // this is good, we want this exception to bubble up...
            }
            catch (TargetInvocationException)
            {
                Assert.Fail("Must have unwrapped this.");
            }
        }

        [Test]
        public void FactoryWrapsObjectInSingletonTargetSource()
        {
            IObjectFactory bf = new XmlObjectFactory(
                new ReadOnlyXmlTestResource("proxyFactoryTargetSourceTests.xml",
                                            GetType()));
            ITestObject tb = (ITestObject)bf.GetObject("viaTargetSource");
            Assert.IsTrue(tb.Name.Equals("Adam"));
            ProxyFactoryObject pfb = (ProxyFactoryObject)bf.GetObject("&viaTargetSource");
            Assert.IsTrue(typeof(ITestObject).IsAssignableFrom(pfb.ObjectType), "Has correct object type");
            Assert.AreEqual(typeof(SingletonTargetSource), pfb.TargetSource.GetType(), "Incorrect target source, expected singleton");
        }

        [Test(Description = "http://opensource.atlassian.com/projects/spring/browse/SPRNET-293")]
        public void SupportsTransparentProxyAsTarget()
        {
            AppDomain domain = null;
            try
            {
                AppDomainSetup setup = new AppDomainSetup();
                setup.ApplicationBase = Environment.CurrentDirectory;
                domain = AppDomain.CreateDomain("Spring", new Evidence(AppDomain.CurrentDomain.Evidence), setup);
                object command = domain.CreateInstanceAndUnwrap(GetType().Assembly.FullName, typeof(RemotableCommand).FullName);

                ProxyFactoryObject fac = new ProxyFactoryObject();
                fac.AddInterface(typeof(ICommand));
                fac.AddAdvice(new NopInterceptor());
                fac.Target = command;

                IAdvised advised = fac.GetObject() as IAdvised;
                Assert.IsNotNull(advised);

                ICommand cmd = fac.GetObject() as ICommand;
                Assert.IsNotNull(cmd);

                cmd.Execute();
            }
            finally
            {
                AppDomain.Unload(domain);
            }
        }

        [Test(Description = "http://opensource.atlassian.com/projects/spring/browse/SPRNET-500")]
        public void NotAccessibleInterfaceProxying()
        {
                const string xml = @"<?xml version='1.0' encoding='UTF-8' ?>
                <objects xmlns='http://www.springframework.net'>
                <object id='MyProxy' type='Spring.Aop.Framework.ProxyFactoryObject, Spring.Aop'>
                    <property name='ProxyInterfaces'>
                        <list>
                            <value>Spring.Aop.Framework.HelperInterface2, Spring.Aop.Tests</value>
                        </list>
                    </property>
                    <property name='TargetName' value='MyTarget' />
                    <property name='InterceptorNames'>
                        <list>
                            <value>MyInterceptor</value>
                        </list>
                    </property>
                </object>
                <object id='MyTarget' type='Spring.Aop.Framework.HelperClassForNotAccessibleInterfaceProxyingTest, Spring.Aop.Tests'/>
              <object id='MyInterceptor' type='Spring.Aop.Interceptor.NopInterceptor'/>
               </objects>";


                MemoryStream stream = new MemoryStream(new UTF8Encoding().GetBytes(xml));
                IResource resource = new InputStreamResource(stream, "Test ProxyFactoryObject");
                XmlObjectFactory objectFactory = new XmlObjectFactory(resource, null);

                HelperInterface2 hc = (HelperInterface2)objectFactory.GetObject("MyProxy");
                Console.WriteLine(hc.SecondDoSomething());
        }

        [Test]
        public void ProxyFactoryObjectIsThreadSafe()
        {
            const int WORKERS = 10;

            AsyncTestMethod[] workers = new AsyncTestMethod[WORKERS];
            for(int i=0;i<WORKERS;i++)
            {
                workers[i] = new AsyncTestMethod( 1, new ThreadStart( CallGetObject ) );
            }

            for(int i=0;i<WORKERS;i++)
            {
                workers[i].Start();
            }

            for(int i=0;i<WORKERS;i++)
            {
                workers[i].AssertNoException();
            }
        }

        private void CallGetObject()
        {
            ProxyFactoryObject proxyFactory = (ProxyFactoryObject) this.factory.GetObject("&concurrentPrototype");

            ITestObject prevTestObject = null;

            for(int i=0;i<20;i++)
            {
                ITestObject o = proxyFactory.GetObject() as ITestObject;
                Assert.IsNotNull(o);
                Assert.AreNotSame( prevTestObject, o );
                prevTestObject = o;
                Thread.Sleep( 0 );
            }
        }

        [Test]
        public void ProxyTypeDoesntChangeIfSameConfig()
        {
            ProxyFactoryObject factoryObject = (ProxyFactoryObject) this.factory.GetObject( "&concurrentPrototype" );
            Type testObjectType1 = factoryObject.GetObject().GetType();
            Type testObjectType2 = factoryObject.GetObject().GetType();

            Assert.AreSame(testObjectType1, testObjectType2);
        }

        [Test]
        public void ProxyTypeChangesIfConfigChanges()
        {
            ProxyFactoryObject factoryObject = (ProxyFactoryObject) this.factory.GetObject( "&concurrentPrototype" );
            Type testObjectType1 = factoryObject.GetObject().GetType();

            factoryObject.Interfaces = new Type[] {};
            Type testObjectType2 = factoryObject.GetObject().GetType();

            Assert.AreNotSame( testObjectType1,testObjectType2 );
        }

        #region WorkerThread Class

        public class WorkerThread
        {
            private Exception _exception;
            private Thread _thread;
            private WaitCallback _callback;
            private object _arg;

            public WorkerThread(string name, WaitCallback callback,object arg)
            {
                this._arg = arg;
                this._callback = callback;
                _thread = new Thread( new ThreadStart( Run ) );
                _thread.IsBackground = true;
                _thread.Name = name;
            }

            public void Start()
            {
                _thread.Start();
            }

            public void Join()
            {
                if (_thread.IsAlive)
                {
                    _thread.Join();
                }
            }

            public Exception Exception
            {
                get { return this._exception; }
            }

            private void Run()
            {
                try
                {
                    _callback( _arg );
                }
                catch(Exception ex)
                {
                    _exception = ex;
                }
            }
        }

        #endregion WorkerThread Class

        #region Helper Classes

        public interface ICommand
        {
            void Execute();
        }

        public sealed class BadCommand : ICommand
        {
            public void Execute()
            {
                throw new NotImplementedException();
            }
        }

        public sealed class GoodCommand : ICommand
        {
            public void Execute()
            {
            }
        }

        public sealed class RemotableCommand : MarshalByRefObject, ICommand
        {
            public void Execute()
            {
            }
        }

        /// <summary>
        /// Fires only on void methods. Saves list of methods intercepted.
        /// </summary>
        public class PointcutForVoid : DynamicMethodMatcherPointcutAdvisor
        {
            private class AnonymousClassMethodInterceptor1 : IMethodInterceptor
            {
                public Object Invoke(IMethodInvocation invocation)
                {
                    methodNames.Add(invocation.Method.Name);
                    return invocation.Proceed();
                }
            }

            public static IList methodNames;

            public static void Reset()
            {
                methodNames.Clear();
            }

            public PointcutForVoid()
                : base(new AnonymousClassMethodInterceptor1())
            {
            }

            /// <summary>
            /// Must fire only if it returns void.
            /// </summary>
            public override bool Matches(MethodInfo method, Type targetType, object[] args)
            {
                return method.ReturnType == typeof(void);
            }

            static PointcutForVoid()
            {
                methodNames = new ArrayList();
            }
        }

        /// <summary> Aspect interface</summary>
        public interface IAddedGlobalInterface
        {
            int GlobalsAdded { get; set; }
        }

        /// <summary> Use as a global interceptor. Checks that
        /// global interceptors can add aspect interfaces.
        /// NB: Add only via global interceptors in XML file.
        /// </summary>
        public class GlobalIntroduction : IAdvice, IAddedGlobalInterface
        {
            private int globalsAdded = -1;

            public int GlobalsAdded
            {
                get { return globalsAdded; }
                set { globalsAdded = value; }
            }
        }

        private class EvilMethodInterceptor : IMethodInterceptor
        {
            private Exception ex;

            public EvilMethodInterceptor(Exception ex)
            {
                this.ex = ex;
            }

            public object Invoke(IMethodInvocation invocation)
            {
                throw ex;
            }
        }

        #endregion
    }

    #region HelpersForNotAccessibleInterfaceProxyingTest

    public class HelperClassForNotAccessibleInterfaceProxyingTest : HelperInterface1, HelperInterface2
    {
        public string FirstDoSomething()
        {
            return "FirstDoSomething (internal interface implementation)";
        }

        public string SecondDoSomething()
        {
            return "SecondDoSomething (public interface implementation)";
        }
    }

    internal interface HelperInterface1
    {
        string FirstDoSomething();
    }

    public interface HelperInterface2
    {
        string SecondDoSomething();
    }

    #endregion


}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.