private bool IsVisible(PropertyDescriptor pd) { if (SerializationUtility.IsSerializableDataMember(pd)) { return(true); } // Even if this property doesn't have [Include], we consider this property to // be visible when its type is a known entity type, as it implies that there // was a query operation for it. Type associatedEntityType = TypeUtility.GetElementType(pd.PropertyType); if (associatedEntityType != null && this.domainServiceDescription.EntityTypes.Contains(associatedEntityType)) { return(true); } if (TypeUtility.FindIEnumerable(pd.ComponentType) != null) { // REVIEW: Find a better way to deal with this... if (pd.Name.Equals("Count", StringComparison.Ordinal)) { return(true); } } return(false); }
/// <summary> /// Based on the operation type specified, create the default corresponding attribute /// if it hasn't been specified explicitly, and add it to the attributes collection. /// </summary> private void InitializeOperationAttribute() { if (this._operationAttribute != null) { return; } bool attributeCreated = false; switch (this.Operation) { case DomainOperation.Query: this._operationAttribute = this._attributes[typeof(QueryAttribute)]; if (this._operationAttribute == null) { QueryAttribute qa = new QueryAttribute(); // singleton returning query methods aren't composable qa.IsComposable = TypeUtility.FindIEnumerable(this.ReturnType) != null; this._operationAttribute = qa; attributeCreated = true; } break; case DomainOperation.Insert: this._operationAttribute = this._attributes[typeof(InsertAttribute)]; if (this._operationAttribute == null) { this._operationAttribute = new InsertAttribute(); attributeCreated = true; } break; case DomainOperation.Update: this._operationAttribute = this._attributes[typeof(UpdateAttribute)]; if (this._operationAttribute == null) { this._operationAttribute = new UpdateAttribute(); attributeCreated = true; } break; case DomainOperation.Delete: this._operationAttribute = this._attributes[typeof(DeleteAttribute)]; if (this._operationAttribute == null) { this._operationAttribute = new DeleteAttribute(); attributeCreated = true; } break; case DomainOperation.Invoke: this._operationAttribute = this._attributes[typeof(InvokeAttribute)]; if (this._operationAttribute == null) { this._operationAttribute = new InvokeAttribute(); attributeCreated = true; } break; case DomainOperation.Custom: this._operationAttribute = this._attributes[typeof(EntityActionAttribute)]; if (this._operationAttribute == null) { this._operationAttribute = new EntityActionAttribute(); attributeCreated = true; } break; default: break; } if (attributeCreated) { if (this._attributes == null) { this._attributes = new AttributeCollection(this._operationAttribute); } else { this._attributes = AttributeCollection.FromExisting(this._attributes, this._operationAttribute); } } }
/// <summary> /// Test helper for invoke operation return type testing /// </summary> /// <typeparam name="T">expected return type</typeparam> /// <param name="provider">an instance to the test scenarios domain service</param> /// <param name="testMethod">the invoke operation to be tested</param> /// <param name="inputValue">input value to the test method. This should /// be of type T</param> private void VerifyOnlineMethodReturn <T>(TestProvider_Scenarios provider, ReturnTestDelegate <T> testMethod, T inputValue) { InvokeOperation invoke = null; EnqueueCallback(delegate { Type[] genericArguments = typeof(T).GetGenericArguments(); string genericType = (genericArguments != null && genericArguments.Length > 0) ? ("<" + genericArguments[0].Name + ">") : ""; Console.WriteLine("Verify invoke operation using return type '{0}{1}'...", typeof(T).Name, genericType); // call invoke operation with the input value invoke = testMethod(inputValue, TestHelperMethods.DefaultOperationAction, null); }); // wait for invoke operation to return. EnqueueConditional(() => invoke.IsComplete); EnqueueCallback(delegate { // verify invocation completed succesfully Assert.IsNull(invoke.Error, string.Format("InvokeEventArgs.Error should be null.\r\nMessage: {0}\r\nStack Trace:\r\n{1}", invoke.Error != null ? invoke.Error.Message : string.Empty, invoke.Error != null ? invoke.Error.StackTrace : string.Empty)); Assert.IsFalse(invoke.ValidationErrors.Any()); // verify the inputValue is correctly round-tripped back as returnValue if (inputValue == null) { Assert.IsNull(invoke.Value); } else { if (TypeUtility.FindIEnumerable(typeof(T)) == null) { Assert.AreEqual(inputValue.GetType(), invoke.Value.GetType()); } else { Assert.AreEqual(TypeUtility.GetElementType(inputValue.GetType()), TypeUtility.GetElementType(invoke.Value.GetType())); } if (TypeUtility.GetNonNullableType(typeof(T)) == typeof(DateTime)) { DateTime returnedDate = (DateTime)invoke.Value; Assert.AreEqual(((DateTime)(object)inputValue).Kind, returnedDate.Kind); Assert.AreEqual(inputValue, returnedDate); } else if (TypeUtility.GetNonNullableType(typeof(T)) == typeof(DateTimeOffset)) { DateTimeOffset returnedDate = (DateTimeOffset)invoke.Value; Assert.AreEqual(((DateTimeOffset)(object)inputValue).Offset.Ticks, returnedDate.Offset.Ticks); Assert.AreEqual(inputValue, returnedDate); } else if (typeof(T) == typeof(byte[])) { // if T is byte[], we verify count matches as well as the elements matching Assert.AreEqual(typeof(byte[]), invoke.Value.GetType()); byte[] returnedArray = invoke.Value as byte[]; byte[] inputArray = inputValue as byte[]; Assert.AreEqual(inputArray.Length, returnedArray.Length); for (int i = 0; i < returnedArray.Length; i++) { Assert.AreEqual(inputArray[i], returnedArray[i], string.Format("array elements {0} should be equal", i)); } } else if (TypeUtility.IsPredefinedListType(typeof(T))) { IEnumerable <object> inputEnumerable = ((IEnumerable)inputValue).Cast <object>(); IEnumerable <object> resultEnumerable = ((IEnumerable)invoke.Value).Cast <object>(); Assert.IsTrue(inputEnumerable.SequenceEqual(resultEnumerable)); } else { Assert.AreEqual(inputValue, invoke.Value); } } Console.WriteLine("...Completed"); }); }