public void CreateChildTransactionMode_WithNonLoadableOutParameter()
        {
            ExecuteDelegateInWxeFunction(
                WxeTransactionMode <ClientTransactionFactory> .CreateRoot,
                (parentCtx, parentF) =>
            {
                var subFunction = new DomainObjectParameterTestTransactedFunction(
                    WxeTransactionMode <ClientTransactionFactory> .CreateChildIfParent,
                    (ctx, f) =>
                {
                    f.OutParameter      = SampleObject.NewObject();
                    f.OutParameterArray = new[] { SampleObject.NewObject() };
                },
                    null,
                    null);

                subFunction.SetParentStep(parentF);
                subFunction.Execute(parentCtx);

                var parentTransaction = parentF.Transaction.GetNativeTransaction <ClientTransaction>();
                Assert.That(parentTransaction.IsEnlisted(subFunction.OutParameter), Is.True);
                Assert.That(subFunction.OutParameter.State, Is.EqualTo(StateType.Invalid));
                Assert.That(() => subFunction.OutParameter.EnsureDataAvailable(), Throws.TypeOf <ObjectInvalidException>());

                Assert.That(parentTransaction.IsEnlisted(subFunction.OutParameterArray[0]), Is.True);
                Assert.That(subFunction.OutParameterArray[0].State, Is.EqualTo(StateType.Invalid));
                Assert.That(() => subFunction.OutParameterArray[0].EnsureDataAvailable(), Throws.TypeOf <ObjectInvalidException>());
            });
        }
        public void CreateChildTransactionMode_WithNonLoadableInParameter()
        {
            ExecuteDelegateInWxeFunction(
                WxeTransactionMode <ClientTransactionFactory> .CreateRoot,
                (parentCtx, parentF) =>
            {
                var inParameter = SampleObject.NewObject();
                inParameter.Delete();

                var inParameterArray = new[] { SampleObject.NewObject() };
                inParameterArray[0].Delete();

                var subFunction = new DomainObjectParameterTestTransactedFunction(
                    WxeTransactionMode <ClientTransactionFactory> .CreateChildIfParent,
                    (ctx, f) =>
                {
                    Assert.That(f.InParameter.State, Is.EqualTo(StateType.Invalid));
                    Assert.That(() => f.InParameter.EnsureDataAvailable(), Throws.TypeOf <ObjectInvalidException> ());

                    Assert.That(f.InParameterArray[0].State, Is.EqualTo(StateType.Invalid));
                    Assert.That(() => f.InParameterArray[0].EnsureDataAvailable(), Throws.TypeOf <ObjectInvalidException> ());
                },
                    inParameter,
                    inParameterArray);

                subFunction.SetParentStep(parentF);
                subFunction.Execute(parentCtx);
            });
        }
        public void CreateChildTransactionMode_InAndOutParametersCanBeUsed()
        {
            ExecuteDelegateInWxeFunction(
                WxeTransactionMode <ClientTransactionFactory> .CreateRoot,
                (parentCtx, parentF) =>
            {
                var inParameter                   = SampleObject.NewObject();
                var inParameterArray              = new[] { SampleObject.NewObject() };
                inParameter.Int32Property         = 7;
                inParameterArray[0].Int32Property = 8;

                var parentTransaction = parentF.Transaction.GetNativeTransaction <ClientTransaction> ();

                var subFunction = new DomainObjectParameterTestTransactedFunction(
                    WxeTransactionMode <ClientTransactionFactory> .CreateChildIfParent,
                    (ctx, f) =>
                {
                    var clientTransaction = f.Transaction.GetNativeTransaction <ClientTransaction> ();
                    Assert.That(clientTransaction, Is.Not.Null.And.SameAs(ClientTransaction.Current));
                    Assert.That(clientTransaction, Is.Not.SameAs(parentTransaction));
                    Assert.That(clientTransaction.ParentTransaction, Is.SameAs(parentTransaction));

                    Assert.That(clientTransaction.IsEnlisted(f.InParameter), Is.True);
                    Assert.That(clientTransaction.IsEnlisted(f.InParameterArray[0]));

                    // Since this function is running in a subtransaction, the properties set in the parent transaction are visible from here.
                    Assert.That(f.InParameter.Int32Property, Is.EqualTo(7));
                    Assert.That(f.InParameterArray[0].Int32Property, Is.EqualTo(8));

                    // Since this function is running in a subtransaction, out parameters are visible within the parent function if the transaction is
                    // committed.
                    f.OutParameter = SampleObject.NewObject();
                    f.OutParameter.Int32Property         = 17;
                    f.OutParameterArray                  = new[] { SampleObject.NewObject(), SampleObject.NewObject() };
                    f.OutParameterArray[0].Int32Property = 4;

                    ClientTransaction.Current.Commit();

                    f.OutParameterArray[1].Int32Property = 5;
                },
                    inParameter,
                    inParameterArray);

                subFunction.SetParentStep(parentF);
                subFunction.Execute(parentCtx);

                var outParameter      = subFunction.OutParameter;
                var outParameterArray = subFunction.OutParameterArray;

                Assert.That(parentTransaction.IsEnlisted(outParameter), Is.True);
                Assert.That(outParameter.Int32Property, Is.EqualTo(17));
                Assert.That(parentTransaction.IsEnlisted(outParameterArray[0]), Is.True);
                Assert.That(outParameterArray[0].Int32Property, Is.EqualTo(4));
                Assert.That(parentTransaction.IsEnlisted(outParameterArray[1]), Is.True);
                Assert.That(outParameterArray[1].Int32Property, Is.Not.EqualTo(4));
            });
        }
        protected void ExecuteDelegateInWxeFunctionWithParameters(
            ITransactionMode transactionMode,
            Action <WxeContext, DomainObjectParameterTestTransactedFunction> testDelegate,
            SampleObject inParameter,
            SampleObject[] inParameterArray,
            out SampleObject outParameter,
            out SampleObject[] outParameterArray)
        {
            var function = new DomainObjectParameterTestTransactedFunction(
                transactionMode,
                testDelegate,
                inParameter,
                inParameterArray);

            function.Execute(Context);

            Assert.That(function.DelegatesExecuted, Is.True);

            outParameter      = function.OutParameter;
            outParameterArray = function.OutParameterArray;
        }
        public void CreateRootTransactionMode_InParametersOfDomainObjectType_CauseException()
        {
            using (ClientTransaction.CreateRootTransaction().EnterDiscardingScope())
            {
                var inParameter      = DomainObjectIDs.ClassWithAllDataTypes1.GetObject <SampleObject> ();
                var inParameterArray = new[] { DomainObjectIDs.ClassWithAllDataTypes2.GetObject <SampleObject> () };

                inParameter.Int32Property         = 7;
                inParameterArray[0].Int32Property = 8;

                var function = new DomainObjectParameterTestTransactedFunction(
                    WxeTransactionMode <ClientTransactionFactory> .CreateRoot, (ctx, f) => { }, inParameter, inParameterArray);
                Assert.That(
                    () => function.Execute(Context),
                    Throws.TypeOf <WxeException>()
                    .With.Message.StringStarting(
                        "One or more of the input parameters passed to the WxeFunction are incompatible with the function's transaction. "
                        + "The following objects are incompatible with the target transaction: ")
                    .And.Message.StringContaining(DomainObjectIDs.ClassWithAllDataTypes1.ToString())
                    .And.Message.StringContaining(DomainObjectIDs.ClassWithAllDataTypes1.ToString())
                    .And.Message.StringEnding(". Objects of type 'Remotion.Data.DomainObjects.IDomainObjectHandle`1[T]' could be used instead."));
            }
        }
        protected void ExecuteDelegateInSubWxeFunctionWithParameters(
            ITransactionMode parentFunctionTransactionMode,
            ITransactionMode subFunctionTransactionMode,
            Action <WxeContext, DomainObjectParameterTestTransactedFunction> testDelegate,
            SampleObject inParameter,
            SampleObject[] inParameterArray,
            out SampleObject outParameter,
            out SampleObject[] outParameterArray)
        {
            var subFunction = new DomainObjectParameterTestTransactedFunction(
                subFunctionTransactionMode,
                testDelegate,
                inParameter,
                inParameterArray);

            var rootFunction = new TransactedFunctionWithChildFunction(parentFunctionTransactionMode, subFunction);

            rootFunction.Execute(Context);

            Assert.That(subFunction.DelegatesExecuted, Is.True);

            outParameter      = subFunction.OutParameter;
            outParameterArray = subFunction.OutParameterArray;
        }