//[TestMethod]
 public void SimpleLazyDemonstration()
 {
     Debug.WriteLine("-- Lazy Demonstration --");
     var simpleLazy = new SimpleLazy<SimpleClass>();
     Debug.WriteLine("Not created yet");
     simpleLazy.Value.Description = "New description";
 }
 /// <summary>
 /// Constructs a new instance of DataServiceOperationContext object
 /// </summary>
 /// <param name="host">RequestMessage instance for the current operation context.</param>
 internal DataServiceOperationContext(IDataServiceHost host)
 {
     Debug.Assert(host != null, "host != null");
     this.hostInterface = host;
     this.lazyMetadataUri = new SimpleLazy<Uri>(() =>
     {
         Debug.Assert(this.AbsoluteServiceUri != null, "Cannot get the metadata uri if the absolute service uri is not initialized");
         return RequestUriProcessor.AppendEscapedSegment(this.AbsoluteServiceUri, XmlConstants.UriMetadataSegment);
     });
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="LazySerializedEntityKey"/> class which uses the same syntax for identity and edit link.
        /// </summary>
        /// <param name="lazyRelativeIdentity">The identity as a lazy string relative to the service URI.</param>
        /// <param name="absoluteServiceUri">The absolute service URI.</param>
        /// <param name="editLinkSuffix">The optional suffix to append to the edit link. Null means nothing will be appended.</param>
        internal LazySerializedEntityKey(SimpleLazy<string> lazyRelativeIdentity, Uri absoluteServiceUri, string editLinkSuffix)
        {
            Debug.Assert(absoluteServiceUri != null && absoluteServiceUri.IsAbsoluteUri, "absoluteServiceUri != null && absoluteServiceUri.IsAbsoluteUri");

            this.lazyAbsoluteEditLinkWithoutSuffix = new SimpleLazy<Uri>(() => RequestUriProcessor.AppendEscapedSegment(absoluteServiceUri, lazyRelativeIdentity.Value));
            this.lazyIdentity = new SimpleLazy<Uri>(() => this.lazyAbsoluteEditLinkWithoutSuffix.Value, false);
            this.lazyAbsoluteEditLink = AppendLazilyIfNeeded(this.lazyAbsoluteEditLinkWithoutSuffix, editLinkSuffix);
            
            SimpleLazy<Uri> relativeEdit = new SimpleLazy<Uri>(() => new Uri(lazyRelativeIdentity.Value, UriKind.Relative), false);
            this.lazyRelativeEditLink = AppendLazilyIfNeeded(relativeEdit, editLinkSuffix);
        }
 public void SimpleLazyOfTDefaultConstructorShouldDelayConstructValue()
 {
     int factoryCallCount = 0;
     SimpleLazy<int> lazy = new SimpleLazy<int>(() =>
     {
         factoryCallCount++;
         return 1;
     });
     factoryCallCount.Should().Be(0);
     lazy.Value.Should().Be(1);
     factoryCallCount.Should().Be(1);
     lazy.Value.Should().Be(1);
     factoryCallCount.Should().Be(1);
 }
 public void SimpleLazyOfTNotThreadSafeShouldDelayConstructValue()
 {
     Uri abcpqr = new Uri("http://abc/pqr", UriKind.Absolute);
     int factoryCallCount = 0;
     SimpleLazy<Uri> lazy = new SimpleLazy<Uri>(() =>
     {
         factoryCallCount++;
         return abcpqr;
     }, false /*isThreadSafe*/);
     factoryCallCount.Should().Be(0);
     lazy.Value.Should().Be(abcpqr);
     factoryCallCount.Should().Be(1);
     lazy.Value.Should().Be(abcpqr);
     factoryCallCount.Should().Be(1);
 }
 public void SimpleLazyOfTThreadSafeShouldDelayConstructValue()
 {
     int factoryCallCount = 0;
     SimpleLazy<string> lazy = new SimpleLazy<string>(() =>
     {
         factoryCallCount++;
         return "foo";
     },
     true /*isThreadSafe*/);
     factoryCallCount.Should().Be(0);
     lazy.Value.Should().Be("foo");
     factoryCallCount.Should().Be(1);
     lazy.Value.Should().Be("foo");
     factoryCallCount.Should().Be(1);
 }
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="jsonLightOutputContext">The output context to write to.</param>
        /// <param name="initContextUriBuilder">Whether contextUriBuilder should be initialized.</param>
        internal ODataJsonLightSerializer(ODataJsonLightOutputContext jsonLightOutputContext, bool initContextUriBuilder = false)
            : base(jsonLightOutputContext)
        {
            Debug.Assert(jsonLightOutputContext != null, "jsonLightOutputContext != null");

            this.jsonLightOutputContext = jsonLightOutputContext;
            this.instanceAnnotationWriter = new SimpleLazy<JsonLightInstanceAnnotationWriter>(() =>
                new JsonLightInstanceAnnotationWriter(new ODataJsonLightValueSerializer(jsonLightOutputContext), jsonLightOutputContext.TypeNameOracle));

            if (initContextUriBuilder)
            {
                // DEVNOTE: grab this early so that any validation errors are thrown at creation time rather than when Write___ is called.
                this.ContextUriBuilder = jsonLightOutputContext.CreateContextUriBuilder();
            }
        }
        /// <summary>
        /// Constructs a new instance of ServiceOperationProvider.
        /// </summary>
        /// <param name="type">Type implementing service operations.</param>
        /// <param name="resourceTypeResolver">Resolver that gives a <see cref="ResourceSet"/> corresponding to given <see cref="ResourceType"/> and <see cref="MethodInfo"/>.</param>
        /// <param name="resourceSetResolver">Resolver that gives a <see cref="ResourceType"/> corresponding to given CLR type.</param>
        public ServiceOperationProvider(Type type, Func<Type, ResourceType> resourceTypeResolver, Func<ResourceType, MethodInfo, ResourceSet> resourceSetResolver)
        {
            WebUtil.CheckArgumentNull(type, "type");
            WebUtil.CheckArgumentNull(resourceTypeResolver, "resourceTypeResolver");
            WebUtil.CheckArgumentNull(resourceSetResolver, "resourceSetResolver");

            if (type.IsAbstract)
            {
                throw new InvalidOperationException(Strings.ServiceOperationProvider_TypeIsAbstract(type));
            }

            this.type = type;
            this.resourceTypeResolver = resourceTypeResolver;
            this.resourceSetResolver = resourceSetResolver;
            this.serviceOperations = new SimpleLazy<List<ServiceOperation>>(this.FindServiceOperations, true);
        }
 /// <summary>
 /// Creates an instance of <see cref="SerializedEntityKey"/> for the given properties and values.
 /// </summary>
 /// <param name="keySerializer">The key serializer to use.</param>
 /// <param name="absoluteServiceUri">The absolute service URI.</param>
 /// <param name="entitySetName">Name of the entity set.</param>
 /// <param name="keyProperties">The key properties.</param>
 /// <param name="getPropertyValue">The callback to get each property's value.</param>
 /// <param name="editLinkSuffix">The suffix to append to the edit-link, or null.</param>
 /// <returns>A serialized-key instance.</returns>
 internal static SerializedEntityKey Create(
     KeySerializer keySerializer, 
     Uri absoluteServiceUri,
     string entitySetName, 
     ICollection<ResourceProperty> keyProperties,
     Func<ResourceProperty, object> getPropertyValue, 
     string editLinkSuffix)
 {
     SimpleLazy<string> lazyRelativeIdentity = new SimpleLazy<string>(() =>
     {
         var builder = new StringBuilder();
         builder.Append(entitySetName);
         keySerializer.AppendKeyExpression(builder, keyProperties, p => p.Name, getPropertyValue);
         return builder.ToString();
     });
         
     return new LazySerializedEntityKey(lazyRelativeIdentity, absoluteServiceUri, editLinkSuffix);
 }
 /// <summary>
 /// Wraps a lazy URI with another that will have the given string appended if it is not null.
 /// </summary>
 /// <param name="lazyUri">The lazy URI to wrap.</param>
 /// <param name="suffix">The suffix for the URI.</param>
 /// <returns>A new lazy URI which will have the suffix, or the same instance if the suffix was null.</returns>
 private static SimpleLazy<Uri> AppendLazilyIfNeeded(SimpleLazy<Uri> lazyUri, string suffix)
 {
     return suffix == null ? lazyUri : new SimpleLazy<Uri>(() => RequestUriProcessor.AppendUnescapedSegment(lazyUri.Value, suffix), false);
 }
        /// <summary>
        /// Asks the provider if the action should be advertised in payloads.
        /// </summary>
        /// <param name="entityToSerialize">The entity to serialize.</param>
        /// <param name="resourceInstanceInFeed">Whether or not the entity is being serialized in a feed.</param>
        /// <param name="serviceOperationWrapper">The service operation wrapper.</param>
        /// <param name="lazyActionTargetUri">Target uri of the action, which will only be generated if needed.</param>
        /// <param name="entityHasMultipleActionsWithSameName">Whether or not there are multiple operations in the current scope with the same name as the current operation.</param>
        /// <param name="odataAction">The ODL object-model representation of the action.</param>
        /// <returns>Whether or not the action should be advertised.</returns>
        private bool AskProviderIfActionShouldBeAdvertised(EntityToSerialize entityToSerialize, bool resourceInstanceInFeed, OperationWrapper serviceOperationWrapper, SimpleLazy<Uri> lazyActionTargetUri, bool entityHasMultipleActionsWithSameName, ref ODataAction odataAction)
        {
            if (this.advertiseServiceAction(serviceOperationWrapper, entityToSerialize.Entity, resourceInstanceInFeed, ref odataAction))
            {
                if (odataAction == null)
                {
                    throw new DataServiceException(500, Microsoft.OData.Service.Strings.DataServiceActionProviderWrapper_AdvertiseServiceActionCannotReturnNullActionToSerialize);
                }

                // Always set target and title if there are overloaded actions.
                if (!entityHasMultipleActionsWithSameName)
                {
                    this.metadataPropertyManager.CheckForUnmodifiedTitle(odataAction, serviceOperationWrapper.Name);
                    this.metadataPropertyManager.CheckForUnmodifiedTarget(odataAction, () => lazyActionTargetUri.Value);
                }

                // make the target link relative
                this.MakeOperationTargetRelativeFromMetadataUriIfJsonLight(odataAction);

                return true;
            }

            odataAction = null;
            return false;
        }
        /// <summary>
        /// Tries to serialize the operation.
        /// </summary>
        /// <param name="entityToSerialize">The entity to serialize.</param>
        /// <param name="resourceInstanceInFeed">Whether or not the entity is being serialized in a feed.</param>
        /// <param name="entityHasMultipleActionsWithSameName">Whether or not there are multiple operations in the current scope with the same name as the current operation.</param>
        /// <param name="serviceOperationWrapper">The service operation wrapper.</param>
        /// <param name="odataAction">The ODL object-model representation of the action.</param>
        /// <returns>Whether or not to serialize the operation.</returns>
        private bool TrySerializeOperation(EntityToSerialize entityToSerialize, bool resourceInstanceInFeed, bool entityHasMultipleActionsWithSameName, OperationWrapper serviceOperationWrapper, out ODataAction odataAction)
        {
            Debug.Assert(serviceOperationWrapper != null, "serviceOperationWrapper != null");

            // We only advertise actions. This is a debug assert because GetServiceOperationsByResourceType only returns actions.
            Debug.Assert(serviceOperationWrapper.Kind == OperationKind.Action, "Only actions can be advertised");

            Uri metadata = this.operationLinkBuilder.BuildMetadataLink(serviceOperationWrapper, entityHasMultipleActionsWithSameName);

            // If the action has OperationParameterBindingKind set to "Always" then we advertise the action without calling "AdvertiseServiceAction".
            bool isAlwaysAvailable = serviceOperationWrapper.OperationParameterBindingKind == OperationParameterBindingKind.Always;

            odataAction = new ODataAction { Metadata = metadata };

            // There is some subtlety to the interaction between action advertisement and whether or not to include title/target on the wire.
            // 
            // 1) If an action is always available:
            //    The provider author does not get a chance to customize the title/target values...
            //    so the values will be based on conventions...
            //    so by default do not write them on the wire
            // 2) If it is only sometimes available:
            //    The values need to be computed to provide them on the instance given to the provider...
            //    but they might not be changed by the provider author...
            //    so compare them to the computed values, and do not write them if they match.
            
            // TODO: Action provider should be able to customize title/target even if the action is 'always' advertised
            // If this gets fixed, then all the behavior should collapse to emulate case #2 above

            // Create a lazy Uri for the target, because we may need it more than once (see case #2 above).
            SimpleLazy<Uri> lazyActionTargetUri = new SimpleLazy<Uri>(() => this.operationLinkBuilder.BuildTargetLink(entityToSerialize, serviceOperationWrapper, entityHasMultipleActionsWithSameName));

            this.metadataPropertyManager.SetTitle(odataAction, isAlwaysAvailable, serviceOperationWrapper.Name);
            this.metadataPropertyManager.SetTarget(odataAction, isAlwaysAvailable, () => lazyActionTargetUri.Value);

            // If the operation is always available,
            // 1. Return true for MetadataQueryOption.All.
            // 2. Return false for MetadataQueryOption.None.
            // 3. Return false for MetadataQueryOption.Default.
            if (isAlwaysAvailable)
            {
                return this.payloadMetadataParameterInterpreter.ShouldIncludeAlwaysAvailableOperation();
            }

            return this.AskProviderIfActionShouldBeAdvertised(entityToSerialize, resourceInstanceInFeed, serviceOperationWrapper, lazyActionTargetUri, entityHasMultipleActionsWithSameName, ref odataAction);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="PrimitiveValueMaterializationPolicy" /> class.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="lazyPrimitivePropertyConverter">The lazy primitive property converter.</param>
 internal PrimitiveValueMaterializationPolicy(IODataMaterializerContext context, SimpleLazy<PrimitivePropertyConverter> lazyPrimitivePropertyConverter)
 {
     this.context = context;
     this.lazyPrimitivePropertyConverter = lazyPrimitivePropertyConverter;
 }
        /// <summary>
        /// Get the stream reference value for media resource (the default stream of an entity).
        /// </summary>
        /// <param name="entityToSerialize">Entity that is currently being serialized.</param>
        /// <param name="title">The title for the element being written.</param>
        /// <returns>
        /// An instance of ODataStreamReferenceValue containing the metadata about the media resource.
        /// </returns>
        private ODataStreamReferenceValue GetMediaResource(EntityToSerialize entityToSerialize, string title)
        {
            Debug.Assert(entityToSerialize.Entity != null, "element != null");
            Debug.Assert(entityToSerialize.ResourceType != null && entityToSerialize.ResourceType.ResourceTypeKind == ResourceTypeKind.EntityType, "type != null && type.ResourceTypeKind == ResourceTypeKind.EntityType");
            Debug.Assert(!string.IsNullOrEmpty(title), "!string.IsNullOrEmpty(title)");

            ODataStreamReferenceValue mediaResource = null;

            // Handle MLE
            if (entityToSerialize.ResourceType.IsMediaLinkEntry)
            {
                string mediaETag;
                Uri readStreamUri;
                string mediaContentType;

                Debug.Assert(entityToSerialize.ResourceType.ResourceTypeKind == ResourceTypeKind.EntityType, "type.ResourceTypeKind == ResourceTypeKind.EntityType");
                this.Service.StreamProvider.GetStreamDescription(entityToSerialize.Entity, null /*null for MLE*/, this.Service.OperationContext, out mediaETag, out readStreamUri, out mediaContentType);
                Debug.Assert(WebUtil.IsETagValueValid(mediaETag, true), "WebUtil.IsETagValueValid(mediaETag, true)");
                Debug.Assert(!string.IsNullOrEmpty(mediaContentType), "!string.IsNullOrEmpty(mediaContentType)");

                mediaResource = new ODataStreamReferenceValue();

                // build the stream's edit link lazily to avoid creating the entity's edit link if it is not needed.
                SimpleLazy<Uri> lazyStreamEditLink = new SimpleLazy<Uri>(() => RequestUriProcessor.AppendEscapedSegment(entityToSerialize.SerializedKey.RelativeEditLink, XmlConstants.UriValueSegment));

                this.PayloadMetadataPropertyManager.SetEditLink(mediaResource, () => lazyStreamEditLink.Value);

                this.PayloadMetadataPropertyManager.SetContentType(mediaResource, mediaContentType);

                // If the stream provider did not provider a read link, then we should use the edit link as the read link.
                this.PayloadMetadataPropertyManager.SetReadLink(mediaResource, () => readStreamUri ?? lazyStreamEditLink.Value);
#pragma warning disable 618
                if (this.contentFormat == ODataFormat.Atom)
#pragma warning restore 618
                {
                    AtomStreamReferenceMetadata mediaResourceAtom = new AtomStreamReferenceMetadata() { EditLink = new AtomLinkMetadata { Title = title } };
                    mediaResource.SetAnnotation(mediaResourceAtom);
                }

                if (!string.IsNullOrEmpty(mediaETag))
                {
                    this.PayloadMetadataPropertyManager.SetETag(mediaResource, mediaETag);
                }
            }

            return mediaResource;
        }