locked
Constraint throws exception while being serialized to XAML (Literal only supports value types...) RRS feed

  • Question

  • I'm validating an ActivityBuilder used as root on a rehosted designer. It all works well and I can see that the XAML is perfectly generated by the designer.

    Now, I've added this constraint to the ActivityBuilder which basically verifies if the root activity is of a certain Type:

     

    private static Constraint<ActivityBuilder> CheckIfRootIsCustomTypeActivity()
     {
     var activityBeingValidated = new DelegateInArgument<ActivityBuilder>();
     var validationContext = new DelegateInArgument<ValidationContext>();
     var assertResult = new Variable<bool>();
    
     return new Constraint<ActivityBuilder>
     {
     DisplayName = "CheckIfRootIsCustomTypeActivity",
     Body = new ActivityAction<ActivityBuilder, ValidationContext>
     {
      Argument1 = activityBeingValidated,
      Argument2 = validationContext,
    
      Handler = new If
      {
      Condition = new InArgument<bool>()
      {
      Expression = new Equal<Type, Type, bool>()
      {
      Left = ExpressionServices.Convert<Type>(c => activityBeingValidated.Get(c).Implementation.GetType()),
      Right = ExpressionServices.Convert<Type>(c => typeof(CustomActivity))
      }
      },
      Then = new AssertValidation
      {
      Assertion = new InArgument<bool>()
      {
      Expression = ExpressionServices.Convert<bool>(c => true)
      },
      Message = new InArgument<string>("Root activity should be a CustomActivity")
      }
      }
     }
     };
     }
    


     

    Once again, the constraint is successfully serialized to XAML by the designer but when I try to validate it (or even run it, for that matter) it throws this:

    Internal constraint exception while running constraint with name 'CheckIfRootIsCustomTypeActivity' against activity of type System.Activities.DynamicActivity

    with name 'DynamicActivity'. Exception was: System.Activities.InvalidWorkflowException: The following errors were encountered while processing the workflow

    tree: 'Literal<Type>': Literal only supports value types and immutable type System.String. The type System.Type cannot be used as a literal.

    Obviously the problem is within that Equal<Type,Type,bool> expression. A previous error indicated me to use ExpressionServices.Convert(), which I did, and now, although serialized, it still isn't validated!

    What can I do to this constraint be validated and runnable through the XAML?







    Saturday, August 20, 2011 12:35 AM

Answers

  • Basically ExpressionServicesConvert is being smart enough to analyze your expression and convert it to an Activity Expression tree.

    However, it then turns out that when it converts

    typeof(CustomActivity))

    in the expression it is interpreting it as

    Literal<Type>(typeof(CustomActivity))

    - and then you getting the error described at runtime as a result of that

    tree: 'Literal<Type>': Literal only supports value types and immutable type System.String. The type System.Type cannot be used as a literal.

    The limitations of Literal<> activity are pretty severe. How to avoid them?

    For some 'non-literalable' types you can use the New activity to instantiate an object, but this doesn't work for System.Type. The closest you could get to constructing a Type would probably be to use InvokeMethod activity on Type.GetType() or similar.

    At that point the input to Type.GetType would probably be your assembly qualified full type name... so at this point you could opt to just do validation on

    activityBeingValidated.Get(c).Implementation.GetType().AssemblyQualifiedName

    directly instead, which is basically the same effect.
    Tim

    • Marked as answer by Andrew_Zhu Monday, August 29, 2011 6:27 AM
    Sunday, August 21, 2011 4:28 AM