/// <summary>
        /// Initializes a new instance of the <see cref="Pipeline"/> class.
        /// </summary>
        /// <param name="processors">The set of <see cref="Processor"/> instances the <see cref="Pipeline"/> instance
        /// will use.</param>
        /// <param name="inArguments">The set of <see cref="ProcessorArgument"/> instances describing the input values
        /// that will be provided to <see cref="Execute"/>.</param>
        /// <param name="outArguments">The set of <see cref="ProcessorArgument"/> instances describing the output
        /// values that will be returned by <see cref="Execute"/>.</param>
        public Pipeline(IEnumerable<Processor> processors, IEnumerable<ProcessorArgument> inArguments, IEnumerable<ProcessorArgument> outArguments)
        {
            if (processors == null)
            {
                throw new ArgumentNullException("processors");
            }

            if (inArguments == null)
            {
                throw new ArgumentNullException("inArguments");
            }

            if (outArguments == null)
            {
                throw new ArgumentNullException("outArguments");
            }

            this.inArguments = inArguments;
            this.outArguments = outArguments;

            List<Processor> workingProcessors = new List<Processor>(processors);
            workingProcessors.Insert(0, new PipelineEntryProcessor(this));
            workingProcessors.Add(new PipelineExitProcessor(this));
            this.Processors = new ProcessorCollection(this, workingProcessors.ToArray());

            this.bindings = new PipelineBindingCollection(this.Processors);
        }
示例#2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Pipeline"/> class.
        /// </summary>
        /// <param name="processors">The set of <see cref="Processor"/> instances the <see cref="Pipeline"/> instance
        /// will use.</param>
        /// <param name="inArguments">The set of <see cref="ProcessorArgument"/> instances describing the input values
        /// that will be provided to <see cref="Execute"/>.</param>
        /// <param name="outArguments">The set of <see cref="ProcessorArgument"/> instances describing the output
        /// values that will be returned by <see cref="Execute"/>.</param>
        public Pipeline(IEnumerable <Processor> processors, IEnumerable <ProcessorArgument> inArguments, IEnumerable <ProcessorArgument> outArguments)
        {
            if (processors == null)
            {
                throw new ArgumentNullException("processors");
            }

            if (inArguments == null)
            {
                throw new ArgumentNullException("inArguments");
            }

            if (outArguments == null)
            {
                throw new ArgumentNullException("outArguments");
            }

            this.inArguments  = inArguments;
            this.outArguments = outArguments;

            List <Processor> workingProcessors = new List <Processor>(processors);

            workingProcessors.Insert(0, new PipelineEntryProcessor(this));
            workingProcessors.Add(new PipelineExitProcessor(this));
            this.Processors = new ProcessorCollection(this, workingProcessors.ToArray());

            this.bindings = new PipelineBindingCollection(this.Processors);
        }
        public void Bind_Can_Bind_One_OutArgument_Multiple_Times()
        {
            MockNonGenericProcessor p1 = new MockNonGenericProcessor();
            p1.SetOutputArguments(new ProcessorArgument("p1Out1", typeof(string)));

            MockNonGenericProcessor p2 = new MockNonGenericProcessor();
            p2.SetInputArguments(new ProcessorArgument("p2In1", typeof(string)));

            MockNonGenericProcessor p3 = new MockNonGenericProcessor();
            p3.SetInputArguments(new ProcessorArgument("p3In1", typeof(string)));

            ProcessorCollection collection = new ProcessorCollection(new MockNonGenericProcessor(), p1, p2, p3);
            PipelineBindingCollection bindings = new PipelineBindingCollection(collection);

            bindings.BindArguments(p1.OutArguments[0], p2.InArguments[0]);
            bindings.BindArguments(p1.OutArguments[0], p3.InArguments[0]);
            Assert.AreEqual(2, bindings.GetBoundToArguments(p1.OutArguments[0]).Count(), "Processor1 OutArgument1 should have been bound to two other arguments.");
            Assert.AreSame(p2.InArguments[0], bindings.GetBoundToArguments(p1.OutArguments[0]).First(), "Processor1 OutArgument1 should have been bound to Processor2 InArgument1.");
            Assert.AreSame(p3.InArguments[0], bindings.GetBoundToArguments(p1.OutArguments[0]).Skip(1).First(), "Processor1 OutArgument1 should have been bound to Processor3 InArgument1.");
            Assert.AreSame(p1.OutArguments[0], bindings.GetBoundToArguments(p2.InArguments[0]).Single(), "Processor2 InArgument1 should have been bound to Processor1 OutArgument1.");
            Assert.AreSame(p1.OutArguments[0], bindings.GetBoundToArguments(p3.InArguments[0]).Single(), "Processor3 InArgument1 should have been bound to Processor1 OutArgument1.");
        }
        public void Bind_Is_Idempotent()
        {
            MockNonGenericProcessor p1 = new MockNonGenericProcessor();
            p1.SetOutputArguments(new ProcessorArgument("p1Out1", typeof(string)));

            MockNonGenericProcessor p2 = new MockNonGenericProcessor();
            p2.SetInputArguments(new ProcessorArgument("p2In1", typeof(string)));

            ProcessorCollection collection = new ProcessorCollection(new MockNonGenericProcessor(), p1, p2);
            PipelineBindingCollection bindings = new PipelineBindingCollection(collection);

            bindings.BindArguments(p1.OutArguments[0], p2.InArguments[0]);
            Assert.AreEqual(1, bindings.GetBoundToArguments(p2.InArguments[0]).Count(), "Processor2 InArgument1 should have been bound to one other argument.");
            Assert.AreEqual(1, bindings.GetBoundToArguments(p1.OutArguments[0]).Count(), "Processor1 OutArgument1 should have been bound to one other argument.");
            Assert.AreSame(p1.OutArguments[0], bindings.GetBoundToArguments(p2.InArguments[0]).First(), "Processor2 InArgument1 should have been bound to Processor1 OutArgument1.");
            Assert.AreSame(p2.InArguments[0], bindings.GetBoundToArguments(p1.OutArguments[0]).First(), "Processor1 OutArgument1 should have been bound to Processor2 InArgument1.");

            bindings.BindArguments(p1.OutArguments[0], p2.InArguments[0]);
            Assert.AreEqual(1, bindings.GetBoundToArguments(p2.InArguments[0]).Count(), "Processor2 InArgument1 should have been bound to one other argument.");
            Assert.AreEqual(1, bindings.GetBoundToArguments(p1.OutArguments[0]).Count(), "Processor1 OutArgument1 should have been bound to one other argument.");
            Assert.AreSame(p1.OutArguments[0], bindings.GetBoundToArguments(p2.InArguments[0]).First(), "Processor2 InArgument1 should have been bound to Processor1 OutArgument1.");
            Assert.AreSame(p2.InArguments[0], bindings.GetBoundToArguments(p1.OutArguments[0]).First(), "Processor1 OutArgument1 should have been bound to Processor2 InArgument1.");
        }
        public void Unbind_With_Out_Argument_On_Processors_Not_In_A_ProcessorCollection_Throws()
        {
            MockNonGenericProcessor p1 = new MockNonGenericProcessor();
            p1.SetInputArguments(new ProcessorArgument("p1In1", typeof(string)));
            ProcessorCollection collection = new ProcessorCollection(new MockNonGenericProcessor(), p1);
            PipelineBindingCollection bindings = new PipelineBindingCollection(collection);

            MockNonGenericProcessor p2 = new MockNonGenericProcessor();
            p2.SetOutputArguments(new ProcessorArgument("p2Out1", typeof(string)));

            ExceptionAssert.ThrowsInvalidOperation(
                "Unbind should have thrown because the out arugment processor does not belong to any processor collection",
                () =>
                {
                    bindings.UnbindArguments(p2.OutArguments[0], p1.InArguments[0]);
                });
        }
        public void Unbind_With_Out_Argument_Not_Attached_To_Processors_Throws()
        {
            MockNonGenericProcessor p1 = new MockNonGenericProcessor();
            p1.SetInputArguments(new ProcessorArgument("p1In1", typeof(string)));
            ProcessorCollection collection = new ProcessorCollection(new MockNonGenericProcessor(), p1);
            PipelineBindingCollection bindings = new PipelineBindingCollection(collection);

            ExceptionAssert.ThrowsInvalidOperation(
                "Unbind should have thrown because the out arugment does not belong to a processor",
                () =>
                {
                    bindings.UnbindArguments(new ProcessorArgument("someName", typeof(string)), p1.InArguments[0]);
                });
        }
        public void Unbind_With_OutArgument_Type_Not_Assignable_To_InArgument_Type_Throws()
        {
            MockNonGenericProcessor p1 = new MockNonGenericProcessor();
            p1.SetOutputArguments(new ProcessorArgument("p1Out1", typeof(object)));

            MockNonGenericProcessor p2 = new MockNonGenericProcessor();
            p2.SetInputArguments(new ProcessorArgument("p2In1", typeof(Uri)));

            ProcessorCollection collection = new ProcessorCollection(new MockNonGenericProcessor(), p1, p2);
            PipelineBindingCollection bindings = new PipelineBindingCollection(collection);

            ExceptionAssert.ThrowsInvalidOperation(
                "Unbind should have thrown because the out arugment is not assignable to the in argument.",
                () =>
                {
                    bindings.UnbindArguments(p1.OutArguments[0], p2.InArguments[0]);
                });
        }
        public void Unbind_With_OutArgument_That_Is_Not_Out_Direction_Throws()
        {
            MockNonGenericProcessor p1 = new MockNonGenericProcessor();
            p1.SetInputArguments(new ProcessorArgument("p1In1", typeof(string)));

            MockNonGenericProcessor p2 = new MockNonGenericProcessor();
            p2.SetInputArguments(new ProcessorArgument("p2In1", typeof(string)));

            ProcessorCollection collection = new ProcessorCollection(new MockNonGenericProcessor(), p1, p2);
            PipelineBindingCollection bindings = new PipelineBindingCollection(collection);

            ExceptionAssert.ThrowsInvalidOperation(
                "Unbind should have thrown because the out arugment is not in the out direction.",
                () =>
                {
                    bindings.UnbindArguments(p1.InArguments[0], p2.InArguments[0]);
                });
        }
        public void Unbind_With_In_Arguments_On_Processors_Not_In_The_Same_ProcessorCollection_Throws()
        {
            MockNonGenericProcessor p1 = new MockNonGenericProcessor();
            p1.SetOutputArguments(new ProcessorArgument("p1Out1", typeof(string)));
            ProcessorCollection collection = new ProcessorCollection(new MockNonGenericProcessor(), p1);
            PipelineBindingCollection bindings = new PipelineBindingCollection(collection);

            MockNonGenericProcessor p2 = new MockNonGenericProcessor();
            p2.SetInputArguments(new ProcessorArgument("p2In1", typeof(string)));
            ProcessorCollection otherCollection = new ProcessorCollection(new MockNonGenericProcessor(), p2);

            ExceptionAssert.ThrowsInvalidOperation(
                "Unbind should have thrown because the in arugment processor belongs to a different processor collection",
                () =>
                {
                    bindings.UnbindArguments(p1.OutArguments[0], p2.InArguments[0]);
                });
        }
        public void Unbind_With_InArgument_Processor_Before_OutArgument_Processor_Throws()
        {
            MockNonGenericProcessor p1 = new MockNonGenericProcessor();
            p1.SetOutputArguments(new ProcessorArgument("p1Out1", typeof(string)));

            MockNonGenericProcessor p2 = new MockNonGenericProcessor();
            p2.SetInputArguments(new ProcessorArgument("p2In1", typeof(string)));

            ProcessorCollection collection = new ProcessorCollection(new MockNonGenericProcessor(), p2, p1);
            PipelineBindingCollection bindings = new PipelineBindingCollection(collection);

            ExceptionAssert.ThrowsInvalidOperation(
                "Unbind should have thrown because processor 1 comes after processor 2.",
                () =>
                {
                    bindings.UnbindArguments(p1.OutArguments[0], p2.InArguments[0]);
                });
        }
        public void Unbind_With_Arguments_On_The_Same_Processor_Throws()
        {
            MockNonGenericProcessor p1 = new MockNonGenericProcessor();
            p1.SetOutputArguments(new ProcessorArgument("p1Out1", typeof(string)));
            p1.SetInputArguments(new ProcessorArgument("p1In1", typeof(string)));
            ProcessorCollection collection = new ProcessorCollection(new MockNonGenericProcessor(), p1);
            PipelineBindingCollection bindings = new PipelineBindingCollection(collection);

            ExceptionAssert.ThrowsInvalidOperation(
                "Unbind should have thrown because the in arugment and out argument belong to the same processor",
                () =>
                {
                    bindings.UnbindArguments(p1.OutArguments[0], p1.InArguments[0]);
                });
        }
        public void UnBind_Removes_The_Binding_If_Arguments_Are_Bound()
        {
            MockNonGenericProcessor p1 = new MockNonGenericProcessor();
            p1.SetOutputArguments(new ProcessorArgument("p1Out1", typeof(string)));

            MockNonGenericProcessor p2 = new MockNonGenericProcessor();
            p2.SetInputArguments(new ProcessorArgument("p2In1", typeof(string)));

            ProcessorCollection collection = new ProcessorCollection(new MockNonGenericProcessor(), p1, p2);
            PipelineBindingCollection bindings = new PipelineBindingCollection(collection);

            bindings.BindArguments(p1.OutArguments[0], p2.InArguments[0]);
            Assert.AreEqual(1, bindings.GetBoundToArguments(p2.InArguments[0]).Count(), "Processor2 InArgument1 should have been bound to one other argument.");
            Assert.AreEqual(1, bindings.GetBoundToArguments(p1.OutArguments[0]).Count(), "Processor1 OutArgument1 should have been bound to one other argument.");
            Assert.AreSame(p1.OutArguments[0], bindings.GetBoundToArguments(p2.InArguments[0]).Single(), "Processor2 InArgument1 should have been bound to Processor1 OutArgument1.");
            Assert.AreSame(p2.InArguments[0], bindings.GetBoundToArguments(p1.OutArguments[0]).Single(), "Processor1 OutArgument1 should have been bound to Processor2 InArgument1.");

            bindings.UnbindArguments(p1.OutArguments[0], p2.InArguments[0]);
            Assert.AreEqual(0, bindings.GetBoundToArguments(p2.InArguments[0]).Count(), "Processor2 InArgument1 should not have been bound to any other arguments.");
            Assert.AreEqual(0, bindings.GetBoundToArguments(p1.OutArguments[0]).Count(), "Processor1 OutArgument1 should not have been bound to any other arguments.");
        }
        public void UnBind_Does_Not_Remove_Other_Bindings_On_An_InArgument()
        {
            MockNonGenericProcessor p1 = new MockNonGenericProcessor();
            p1.SetOutputArguments(new ProcessorArgument("p1Out1", typeof(string)));

            MockNonGenericProcessor p2 = new MockNonGenericProcessor();
            p2.SetOutputArguments(new ProcessorArgument("p2Out1", typeof(string)));

            MockNonGenericProcessor p3 = new MockNonGenericProcessor();
            p3.SetInputArguments(new ProcessorArgument("p3In1", typeof(string)));

            ProcessorCollection collection = new ProcessorCollection(new MockNonGenericProcessor(), p1, p2, p3);
            PipelineBindingCollection bindings = new PipelineBindingCollection(collection);

            bindings.BindArguments(p1.OutArguments[0], p3.InArguments[0]);
            bindings.BindArguments(p2.OutArguments[0], p3.InArguments[0]);

            bindings.UnbindArguments(p1.OutArguments[0], p3.InArguments[0]);
            Assert.AreEqual(1, bindings.GetBoundToArguments(p2.OutArguments[0]).Count(), "Processor2 OutArgument1 should not have been bound to any other arguments.");
            Assert.AreEqual(1, bindings.GetBoundToArguments(p3.InArguments[0]).Count(), "Processor3 InArgument1 should not have been bound to any other arguments.");
            Assert.AreSame(p2.OutArguments[0], bindings.GetBoundToArguments(p3.InArguments[0]).Single(), "Processor3 InArgument1 should have been bound to Processor2 OutArgument1.");
            Assert.AreSame(p3.InArguments[0], bindings.GetBoundToArguments(p2.OutArguments[0]).Single(), "Processor2 OutArgument1 should have been bound to Processor3 InArgument1.");
        }
        public void GetBoundToArguments_Never_Returns_Null()
        {
            MockNonGenericProcessor p1 = new MockNonGenericProcessor();
            p1.SetOutputArguments(new ProcessorArgument("p1Out1", typeof(string)));

            ProcessorArgument arg2 = new ProcessorArgument("arg1", typeof(string));

            ProcessorCollection collection = new ProcessorCollection(new MockNonGenericProcessor(), p1);
            PipelineBindingCollection bindings = new PipelineBindingCollection(collection);

            IEnumerable<ProcessorArgument> boundArguments = bindings.GetBoundToArguments(p1.OutArguments[0]);
            Assert.IsNotNull(boundArguments, "ProcessorBindingCollection.GetBoundArguments should never return null.");
            Assert.AreEqual(0, boundArguments.Count(), "ProcessorBindingCollection.GetBoundArguments should have returned an empty collection.");

            boundArguments = bindings.GetBoundToArguments(arg2);
            Assert.IsNotNull(boundArguments, "ProcessorBindingCollection.GetBoundArguments should never return null.");
            Assert.AreEqual(0, boundArguments.Count(), "ProcessorBindingCollection.GetBoundArguments should have returned an empty collection.");
        }