/// <summary>
        /// Initializes a new instance of the <see cref="DomainServiceHost"/> class with
        /// the type of service and its base addresses specified.
        /// </summary>
        /// <param name="domainServiceType">The type of the <see cref="DomainService"/> to host.</param>
        /// <param name="baseAddresses">
        /// An array of type <see cref="System.Uri"/> that contains the base addresses for 
        /// the hosted service.
        /// </param>
        public DomainServiceHost(Type domainServiceType, params Uri[] baseAddresses)
        {
            if (domainServiceType == null)
            {
                throw new ArgumentNullException("domainServiceType");
            }

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

            EnableClientAccessAttribute att = (EnableClientAccessAttribute)TypeDescriptor.GetAttributes(domainServiceType)[typeof(EnableClientAccessAttribute)];

            // Filter out all non-HTTP addresses.
            HashSet<string> allowedSchemes = DomainServiceHost._allowedSchemes;

            // Additionally filter out HTTP addresses if this DomainService requires a secure endpoint.
            if (att != null && att.RequiresSecureEndpoint)
            {
                allowedSchemes = DomainServiceHost._allowedSecureSchemes;
            }

            // Apply the filter.
            baseAddresses = baseAddresses.Where(addr => allowedSchemes.Contains(addr.Scheme)).ToArray();

            this._domainServiceDescription = DomainServiceDescription.GetDescription(domainServiceType);
            this.InitializeDescription(domainServiceType, new UriSchemeKeyedCollection(baseAddresses));
        }
        /// <summary>
        /// Creates endpoints based on the specified description.
        /// </summary>
        /// <param name="description">The <see cref="DomainServiceDescription"/> of the <see cref="DomainService"/> to create the endpoints for.</param>
        /// <param name="serviceHost">The service host for which the endpoints will be created.</param>
        /// <returns>The endpoints that were created.</returns>
        public override IEnumerable<ServiceEndpoint> CreateEndpoints(DomainServiceDescription description, DomainServiceHost serviceHost)
        {
            Debug.Assert(this.Name != null, "Name has not been set.");
            Debug.Assert(this.domainDataServiceMetadata == null, "this.domainDataServiceMetadata == null");

            if (description.Attributes[typeof(EnableClientAccessAttribute)] != null)
            {
                // The metadata object will tell us which operations we should expose for the OData end point.
                this.domainDataServiceMetadata = new OData.DomainDataServiceMetadata(description);

                // The OData endpoint doesn't expose all operations in the DomainService, but only operations with parameter and return types
                // which are supported by the data service.  WCF doesn't allow us to create a contract without any operation.
                if (this.domainDataServiceMetadata.Sets.Count > 0 || this.domainDataServiceMetadata.ServiceOperations.Count > 0)
                {
                    // Infer the contract from Domain service description.
                    ContractDescription contract = this.CreateContract(description);

                    // Make endpoints that expose the inferred contract on the given base addresses.
                    foreach (Uri address in serviceHost.BaseAddresses)
                    {
                        yield return this.CreateEndpointForAddress(description, contract, address);
                    }
                }
            }
        }
        /// <summary>
        /// Creates a contract from the specified description.
        /// </summary>
        /// <param name="description">The description to create a contract from.</param>
        /// <returns>A <see cref="ContractDescription"/>.</returns>
        private ContractDescription CreateContract(DomainServiceDescription description)
        {
            Type domainServiceType = description.DomainServiceType;

            // PERF: We should consider just looking at [ServiceDescription] directly.
            ServiceDescription serviceDesc = ServiceDescription.GetService(domainServiceType);

            // Use names from [ServiceContract], if specified.
            ServiceContractAttribute sca = TypeDescriptor.GetAttributes(domainServiceType)[typeof(ServiceContractAttribute)] as ServiceContractAttribute;
            if (sca != null)
            {
                if (!String.IsNullOrEmpty(sca.Name))
                {
                    serviceDesc.Name = sca.Name;
                }
                if (!String.IsNullOrEmpty(sca.Namespace))
                {
                    serviceDesc.Name = sca.Namespace;
                }
            }

            ContractDescription contractDesc = new ContractDescription(serviceDesc.Name + this.Name, serviceDesc.Namespace)
            {
                ConfigurationName = serviceDesc.ConfigurationName + this.Name,
                ContractType = domainServiceType
            };

            // Add domain service behavior which takes care of instantiating DomainServices.
            ServiceUtility.EnsureBehavior<DomainServiceBehavior>(contractDesc);

            // Load the ContractDescription from the DomainServiceDescription.
            ServiceUtility.LoadContractDescription(contractDesc, description);

            return contractDesc;
        }
        internal static IQueryable Deserialize(DomainServiceDescription domainServiceDescription, IQueryable query, IEnumerable<ServiceQueryPart> queryParts, QueryResolver queryResolver)
        {
            foreach (ServiceQueryPart part in queryParts)
            {
                switch (part.QueryOperator)
                {
                    case "where":
                        query = DynamicQueryable.Where(query, part.Expression, queryResolver);
                        break;
                    case "orderby":
                        query = DynamicQueryable.OrderBy(query, part.Expression, queryResolver);
                        break;
                    case "skip":
                        query = DynamicQueryable.Skip(query, Convert.ToInt32(part.Expression, System.Globalization.CultureInfo.InvariantCulture));
                        break;
                    case "take":
                        query = DynamicQueryable.Take(query, Convert.ToInt32(part.Expression, System.Globalization.CultureInfo.InvariantCulture));
                        break;
                }
            }

            // Perform any required post processing transformations to the
            // expression tree
            Expression expr = PostProcessor.Process(domainServiceDescription, query.Expression);
            query = query.Provider.CreateQuery(expr);

            return query;
        }
        public override void ProcessGeneratedCode(DomainServiceDescription domainServiceDescription, CodeCompileUnit codeCompileUnit, IDictionary<Type, CodeTypeDeclaration> typeMapping)
        {
            // Get a reference to the entity class
            CodeTypeDeclaration codeGenEntity = typeMapping[typeof(TestEntity)];

            AppDomain appDomain = AppDomain.CurrentDomain;
            AppDomainSetup setup = appDomain.SetupInformation;

            string baseDir = appDomain.BaseDirectory;
            codeGenEntity.Comments.Add(new CodeCommentStatement("[CodeProcessor] BaseDirectory:" + baseDir));

            Configuration cfg = WebConfigurationManager.OpenWebConfiguration(null);

            AuthenticationSection authSection = (AuthenticationSection)cfg.GetSection("system.web/authentication");
            FormsAuthenticationConfiguration formsAuth = authSection.Forms;
            if (formsAuth != null)
            {
                codeGenEntity.Comments.Add(new CodeCommentStatement("[CodeProcessor] Authentication:forms"));
            }

            ConnectionStringsSection connSect = cfg.ConnectionStrings;
            if (connSect != null)
            {
                ConnectionStringSettingsCollection connColl = connSect.ConnectionStrings;
                foreach (ConnectionStringSettings connSetting in connColl)
                {
                    codeGenEntity.Comments.Add(new CodeCommentStatement("[CodeProcessor] ConnectionString:" + connSetting.ConnectionString));
                }
            }
        }
        /// <summary>
        /// Generates complex object code.
        /// </summary>
        /// <param name="complexObjectType">Type of the complex object for which the proxy is to be generates.</param>
        /// <param name="domainServiceDescription">The DomainServiceDescription for the domain service associated with this complex type.</param>
        /// <param name="clientCodeGenerator">ClientCodeGenerator object for this instance.</param>
        /// <returns>The generated complex object code.</returns>
        public string Generate(Type complexObjectType, DomainServiceDescription domainServiceDescription, ClientCodeGenerator clientCodeGenerator)
        {
            this.Type = complexObjectType;
            this.ClientCodeGenerator = clientCodeGenerator;
            this.DomainServiceDescription = domainServiceDescription;

            return this.GenerateDataContractProxy();
        }
            private PostProcessor(DomainServiceDescription domainServiceDescription)
            {
                if (domainServiceDescription == null)
                {
                    throw new ArgumentNullException("domainServiceDescription");
                }

                this.domainServiceDescription = domainServiceDescription;
            }
 /// <summary>
 /// Creates endpoints based on the specified description.
 /// </summary>
 /// <param name="description">The <see cref="DomainServiceDescription"/> of the <see cref="DomainService"/> to create the endpoints for.</param>
 /// <param name="serviceHost">The service host for which the endpoints will be created.</param>
 /// <returns>The endpoints that were created.</returns>
 public override IEnumerable<ServiceEndpoint> CreateEndpoints(DomainServiceDescription description, DomainServiceHost serviceHost)
 {
     ContractDescription contract = this.CreateContract(description);
     List<ServiceEndpoint> endpoints = new List<ServiceEndpoint>();
     foreach (Uri address in serviceHost.BaseAddresses)
     {
         endpoints.Add(this.CreateEndpointForAddress(contract, address));
     }
     return endpoints;
 }
 /// <summary>
 /// Creates endpoints based on the specified description.
 /// </summary>
 /// <param name="description">The <see cref="DomainServiceDescription"/> of the <see cref="DomainService"/> to create the endpoints for.</param>
 /// <param name="serviceHost">The service host for which the endpoints will be created.</param>
 /// <returns>The endpoints that were created.</returns>
 public override IEnumerable<ServiceEndpoint> CreateEndpoints(DomainServiceDescription description, DomainServiceHost serviceHost)
 {
     ContractDescription contract = this.CreateContract(description);
     contract.Behaviors.Add(new ServiceMetadataContractBehavior() { MetadataGenerationDisabled = true });
     List<ServiceEndpoint> endpoints = new List<ServiceEndpoint>();
     foreach (Uri address in serviceHost.BaseAddresses)
     {
         endpoints.Add(this.CreateEndpointForAddress(contract, address));
     }
     return endpoints;
 }
 public static void GenerateEntitiesMetadataJsonMap(DomainServiceDescription description)
 {
     foreach (Type entityType in description.EntityTypes)
     {
         entitiesMetadata.Add(new TypeMetadata(entityType));
     }
     foreach (Type complexType in description.ComplexTypes)
     {
         entitiesMetadata.Add(new TypeMetadata(complexType));
     }
 }
        /// <summary>
        /// Constructs a description based on the specified <see cref="DomainServiceDescription"/>.
        /// </summary>
        /// <param name="baseDescription">The base <see cref="DomainServiceDescription"/></param>
        internal DomainServiceDescription(DomainServiceDescription baseDescription)
        {
            if (baseDescription == null)
            {
                throw new ArgumentNullException("baseDescription");
            }

            this._domainServiceType = baseDescription._domainServiceType;
            this._attributes = baseDescription._attributes;
            this._operationEntries.AddRange(baseDescription._operationEntries);
        }
        /// <summary>
        /// Creates a set of WCF REST service endpoints in the <see cref="OpenRiaServices.DomainServices.Hosting.DomainServiceHost"/> which 
        /// expose traces of WCF services in the ATOM, XML, or HTML format. One WCF REST endpoint is added for each HTTP or HTTPS base address from the specified serviceHost.
        /// The address of the endpoint is obtained by appending the name of the TracingDomainServiceEndpointFactory as specified in the domainServices section of the configuration file
        /// to the base address. Furthermore, the UriTemplate of each of the endpoints is specified by the <see cref="WcfTraceService"/> service contract and allows for selection of the 
        /// response contract between ATOM, XML, or HTML. 
        /// </summary>
        /// <param name="description">WCF RIA service description.</param>
        /// <param name="serviceHost">Service host to which endpoints will be added.</param>
        /// <returns>The collection of endpoints.</returns>
        public override IEnumerable<ServiceEndpoint> CreateEndpoints(DomainServiceDescription description, DomainServiceHost serviceHost)
        {
            if (serviceHost == null)
            {
                throw new ArgumentNullException("serviceHost");
            }

            if (this.Parameters["maxEntries"] != null)
            {
                int maxEntries;
                if (int.TryParse(this.Parameters["maxEntries"], out maxEntries))
                {
                    InMemoryTraceListener.MaxEntries = maxEntries;
                }
                else
                {
                    throw new InvalidOperationException(Resx.MaxEntriesAttributeMustBeAPositiveInteger);
                }
            }

            ContractDescription contract = ContractDescription.GetContract(typeof(WcfTraceService));
            contract.Behaviors.Add(new ServiceMetadataContractBehavior { MetadataGenerationDisabled = true });
            
            List<ServiceEndpoint> tracingEndpoints = new List<ServiceEndpoint>();
            foreach (Uri baseAddress in serviceHost.BaseAddresses)
            {
                WebHttpBinding binding = new WebHttpBinding();
                if (baseAddress.Scheme.Equals(Uri.UriSchemeHttps))
                {
                    binding.Security.Mode = WebHttpSecurityMode.Transport;
                }
                else if (!baseAddress.Scheme.Equals(Uri.UriSchemeHttp))
                {
                    continue;
                }

                ServiceEndpoint endpoint = new ServiceEndpoint(contract, binding, new EndpointAddress(baseAddress.OriginalString + "/" + this.Name));
                endpoint.Behaviors.Add(new WebHttpBehavior());
                endpoint.Behaviors.Add(new TracingEndpointBehavior { ServiceHost = serviceHost });
                
                tracingEndpoints.Add(endpoint);
            }
            
            return tracingEndpoints;
        }
        public OperationContext(DomainServiceContext domainServiceContext, DomainService domainService, DomainServiceDescription domainServiceDescription)
        {
            if (domainServiceContext == null)
            {
                throw new ArgumentNullException("domainServiceContext");
            }
            if (domainService == null)
            {
                throw new ArgumentNullException("domainService");
            }
            if (domainServiceDescription == null)
            {
                throw new ArgumentNullException("domainServiceDescription");
            }

            this._domainServiceContext = domainServiceContext;
            this._domainService = domainService;
            this._domainServiceDescription = domainServiceDescription;
        }
        /// <summary>
        /// Creates a contract description for the domain data service endpoint based on the domain service description.
        /// </summary>
        /// <param name="description">Domain data service description.</param>
        /// <returns>Contract description for the domain data service endpoint.</returns>
        private ContractDescription CreateContract(DomainServiceDescription description)
        {
            Type domainServiceType = description.DomainServiceType;

            ServiceDescription serviceDesc = ServiceDescription.GetService(domainServiceType);

            // Use names from [ServiceContract], if specified.
            ServiceContractAttribute sca = TypeDescriptor.GetAttributes(domainServiceType)[typeof(ServiceContractAttribute)] as ServiceContractAttribute;
            if (sca != null)
            {
                if (!String.IsNullOrEmpty(sca.Name))
                {
                    serviceDesc.Name = sca.Name;
                }
                if (!String.IsNullOrEmpty(sca.Namespace))
                {
                    serviceDesc.Name = sca.Namespace;
                }
            }

            ContractDescription contractDesc = new ContractDescription(serviceDesc.Name + this.Name, serviceDesc.Namespace)
            {
                ConfigurationName = serviceDesc.ConfigurationName + this.Name,
                ContractType = domainServiceType
            };

            // Disable metadata generation for the domain data service contract.
            contractDesc.Behaviors.Add(new ServiceMetadataContractBehavior(true));

            // Add domain service behavior which takes care of instantiating DomainServices.
            ServiceUtils.EnsureBehavior<DomainDataServiceContractBehavior>(contractDesc);

            // Load the ContractDescription from the DomainServiceDescription.
            this.LoadContractDescription(contractDesc, description);

            return contractDesc;
        }
        /// <summary>
        /// Creates an endpoint based on the specified address.
        /// </summary>
        /// <param name="domainServiceDescription">Domain service description from which the <paramref name="contract"/> was inferred.</param>
        /// <param name="contract">The endpoint's contract.</param>
        /// <param name="address">The endpoint's base address.</param>
        /// <returns>An endpoint.</returns>
        private ServiceEndpoint CreateEndpointForAddress(DomainServiceDescription domainServiceDescription, ContractDescription contract, Uri address)
        {
            WebHttpBinding binding = new WebHttpBinding();
            binding.MaxReceivedMessageSize = Int32.MaxValue;
            ServiceUtils.SetReaderQuotas(binding.ReaderQuotas);

            if (address.Scheme.Equals(Uri.UriSchemeHttps))
            {
                binding.Security.Mode = WebHttpSecurityMode.Transport;
            }
            else if (ServiceUtils.CredentialType != HttpClientCredentialType.None)
            {
                binding.Security.Mode = WebHttpSecurityMode.TransportCredentialOnly;
            }

            if (ServiceUtils.CredentialType != HttpClientCredentialType.None)
            {
                binding.Security.Transport.ClientCredentialType = ServiceUtils.CredentialType;
            }

            ServiceEndpoint ep = new ServiceEndpoint(contract, binding, new EndpointAddress(address.OriginalString + "/" + this.Name));

            // Data service end point has data service behavior.
            ep.Behaviors.Add(new DomainDataServiceEndpointBehavior()
            {
                DomainDataServiceMetadata = this.domainDataServiceMetadata,
                DefaultBodyStyle = WebMessageBodyStyle.Wrapped
            });

            return ep;
        }
 /// <summary>
 /// Geterates the DomainContext class.
 /// </summary>
 /// <param name="domainServiceDescription">DomainServcieDescription for the domain service for which the proxy is to be generated.</param>
 /// <param name="clientCodeGenerator">ClientCodeGenerator object for this instance.</param>
 /// <returns>The generated DomainContext class code.</returns>
 public string Generate(DomainServiceDescription domainServiceDescription, ClientCodeGenerator clientCodeGenerator)
 {
     this.DomainServiceDescription = domainServiceDescription;
     this.ClientCodeGenerator = clientCodeGenerator;
     return this.GenerateDomainContextClass();
 }
 internal static string GetDomainContextTypeName(DomainServiceDescription domainServiceDescription)
 {
     string domainContextTypeName = domainServiceDescription.DomainServiceType.Name;
     if (domainContextTypeName.EndsWith("Service", StringComparison.Ordinal))
     {
         domainContextTypeName = domainContextTypeName.Substring(0, domainContextTypeName.Length - 7 /* "Service".Length */) + "Context";
     }
     return domainContextTypeName;
 }
 internal CodeMemberShareKind GetDomainContextTypeShareKind(DomainServiceDescription domainServiceDescription)
 {
     Type domainServiceType = domainServiceDescription.DomainServiceType;
     string domainContextTypeName = DomainContextGenerator.GetDomainContextTypeName(domainServiceDescription);
     string fullTypeName = domainServiceType.Namespace + "." + domainContextTypeName;
     CodeMemberShareKind shareKind = this._codeGenerationHost.GetTypeShareKind(fullTypeName);
     return shareKind;
 }
 private void GenerateComplexObjectsIfNotGenerated(DomainServiceDescription dsd, List<Type> generatedComplexObjects)
 {
     foreach (Type t in dsd.ComplexTypes.OrderBy(e => e.Name))
     {
         if (generatedComplexObjects.Contains(t))
         {
             continue;
         }
         CodeMemberShareKind typeShareKind = this.GetTypeShareKind(t);
         if ((typeShareKind & CodeMemberShareKind.SharedByReference) != 0)
         {
             this.CodeGenerationHost.LogError(string.Format(CultureInfo.CurrentCulture, "Type already shared", t));
             continue;
         }
         generatedComplexObjects.Add(t);
         this.Write(this.ComplexObjectGenerator.Generate(t, dsd, this));
     }
 }
        /// <summary>
        /// See <see cref="CodeProcessor.ProcessGeneratedCode"/>.
        /// </summary>
        /// <param name="domainServiceDescription">The domainServiceDescription</param>
        /// <param name="codeCompileUnit">The codeCompileUnit</param>
        /// <param name="typeMapping">The typeMapping</param>
        public override void ProcessGeneratedCode(DomainServiceDescription domainServiceDescription, CodeCompileUnit codeCompileUnit, IDictionary<Type, CodeTypeDeclaration> typeMapping)
        {
            // Make sure the provider extends IAuthentication<T>
            Type genericDomainServiceType;
            AuthenticationCodeProcessor.CheckIAuthentication(domainServiceDescription, out genericDomainServiceType);

            Type userEntityType = genericDomainServiceType.GetGenericArguments()[0];
            AuthenticationCodeProcessor.CheckIUser(userEntityType);

            // Implement IPrincipal and IIdentity in the user type
            CodeTypeDeclaration entityTypeDeclaration;
            typeMapping.TryGetValue(userEntityType, out entityTypeDeclaration);

            if (entityTypeDeclaration != null)
            {
                CodeTypeReference identityInterfaceTypeReference =
                    new CodeTypeReference(typeof(IIdentity)) { Options = CodeTypeReferenceOptions.GlobalReference };
                CodeTypeReference principalInterfaceTypeReference =
                    new CodeTypeReference(typeof(IPrincipal)) { Options = CodeTypeReferenceOptions.GlobalReference };

                entityTypeDeclaration.BaseTypes.Add(identityInterfaceTypeReference);
                entityTypeDeclaration.BaseTypes.Add(principalInterfaceTypeReference);

                ////
                //// private string IIdentitiy.AuthenticationType
                ////
                CodeMemberProperty authenticationTypeProperty = new CodeMemberProperty()
                {
                    Attributes = MemberAttributes.Private | MemberAttributes.Final,
                    HasGet = true,
                    Name = "AuthenticationType",
                    Type = new CodeTypeReference(typeof(string))
                };

                // get { return string.Empty; }
                authenticationTypeProperty.GetStatements.Add(new CodeMethodReturnStatement(
                    new CodePropertyReferenceExpression(
                        new CodeTypeReferenceExpression(typeof(string)),
                        "Empty")));

                authenticationTypeProperty.PrivateImplementationType = identityInterfaceTypeReference;
                entityTypeDeclaration.Members.Add(authenticationTypeProperty);

                ////
                //// public bool IsAuthenticated
                ////
                CodeMemberProperty isAuthenticatedProperty = new CodeMemberProperty()
                {
                    Attributes = MemberAttributes.Public | MemberAttributes.Final,
                    HasGet = true,
                    Name = "IsAuthenticated",
                    Type = new CodeTypeReference(typeof(bool))
                };

                // get { return (true != string.IsNullOrEmpty(this.Name)); }
                isAuthenticatedProperty.GetStatements.Add(
                    new CodeMethodReturnStatement(
                        new CodeBinaryOperatorExpression(
                            new CodePrimitiveExpression(true),
                            CodeBinaryOperatorType.IdentityInequality,
                            new CodeMethodInvokeExpression(
                                new CodeTypeReferenceExpression(typeof(string)),
                                "IsNullOrEmpty",
                                new CodePropertyReferenceExpression(
                                    new CodeThisReferenceExpression(),
                                    "Name")))));

                isAuthenticatedProperty.Comments.AddRange(
                    AuthenticationCodeProcessor.GetDocComments(Resources.ApplicationServices_CommentIsAuth));
                isAuthenticatedProperty.ImplementationTypes.Add(identityInterfaceTypeReference);
                entityTypeDeclaration.Members.Add(isAuthenticatedProperty);

                ////
                //// private string IIdentity.Name
                ////
                // VB Codegen requires us to implement a ReadOnly version of Name as well
                CodeMemberProperty namePropertyExp = new CodeMemberProperty()
                {
                    Attributes = MemberAttributes.Private | MemberAttributes.Final,
                    HasGet = true,
                    Name = "Name",
                    Type = new CodeTypeReference(typeof(string))
                };

                // get { return this.Name; }
                namePropertyExp.GetStatements.Add(
                    new CodeMethodReturnStatement(
                        new CodePropertyReferenceExpression(
                            new CodeThisReferenceExpression(),
                            "Name")));

                namePropertyExp.PrivateImplementationType = identityInterfaceTypeReference;
                entityTypeDeclaration.Members.Add(namePropertyExp);

                ////
                //// private IIdentity IPrincipal.Identity
                ////
                CodeMemberProperty identityProperty = new CodeMemberProperty()
                {
                    Attributes = MemberAttributes.Private | MemberAttributes.Final,
                    HasGet = true,
                    Name = "Identity",
                    Type = identityInterfaceTypeReference,
                };

                // get { return this; }
                identityProperty.GetStatements.Add(
                    new CodeMethodReturnStatement(
                        new CodeThisReferenceExpression()));

                identityProperty.PrivateImplementationType = principalInterfaceTypeReference;
                entityTypeDeclaration.Members.Add(identityProperty);

                ////
                //// public bool IsInRole(string role)
                ////
                CodeMemberMethod isInRoleMethod = new CodeMemberMethod()
                {
                    Attributes = MemberAttributes.Public | MemberAttributes.Final,
                    Name = "IsInRole",
                    ReturnType = new CodeTypeReference(typeof(bool))
                };
                isInRoleMethod.Parameters.Add(
                    new CodeParameterDeclarationExpression(
                        new CodeTypeReference(typeof(string)),
                        "role"));

                // if (this.Roles == null)
                // {
                //     return false;
                // }
                // return this.Roles.Contains(role);
                CodeConditionStatement ifRolesNullStatement = new CodeConditionStatement();
                ifRolesNullStatement.Condition = new CodeBinaryOperatorExpression(
                    new CodePropertyReferenceExpression(
                        new CodeThisReferenceExpression(),
                        "Roles"),
                    CodeBinaryOperatorType.IdentityEquality,
                    new CodePrimitiveExpression(null));
                ifRolesNullStatement.TrueStatements.Add(
                    new CodeMethodReturnStatement(new CodePrimitiveExpression(false)));

                isInRoleMethod.Statements.Add(ifRolesNullStatement);
                isInRoleMethod.Statements.Add(
                    new CodeMethodReturnStatement(
                        new CodeMethodInvokeExpression(
                            new CodeTypeReferenceExpression(
                                new CodeTypeReference(typeof(Enumerable))
                                {
                                    Options = CodeTypeReferenceOptions.GlobalReference
                                }),
                            "Contains",
                            new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), "Roles"),
                            new CodeVariableReferenceExpression("role"))));

                isInRoleMethod.Comments.AddRange(
                    AuthenticationCodeProcessor.GetDocComments(Resources.ApplicationServices_CommentIsInRole));
                isInRoleMethod.ImplementationTypes.Add(principalInterfaceTypeReference);
                entityTypeDeclaration.Members.Add(isInRoleMethod);

                // Changes to Name need to raise change notification for IsAuthenticated. To accomplish this,
                // we'll insert a change event at the end of the "if (this._name != value)" block.
                //
                // >> this.RaisePropertyChanged("IsAuthenticated");
                CodeMemberProperty nameProperty = entityTypeDeclaration.Members.OfType<CodeMemberProperty>().Where(c => c.Name == "Name").First();
                nameProperty.SetStatements.OfType<CodeConditionStatement>().First().TrueStatements.Add(
                    new CodeExpressionStatement(
                        new CodeMethodInvokeExpression(
                            new CodeThisReferenceExpression(),
                            "RaisePropertyChanged",
                            new CodePrimitiveExpression("IsAuthenticated"))));

                // Name should be set to string.Empty by default
                CodeMemberField nameField = entityTypeDeclaration.Members.OfType<CodeMemberField>().Where(c => c.Name == "_name").Single();
                nameField.InitExpression =
                    new CodePropertyReferenceExpression(
                        new CodeTypeReferenceExpression(typeof(string)),
                        "Empty");
            }

            // Set context base type           
            CodeTypeDeclaration providerTypeDeclaration;
            typeMapping.TryGetValue(domainServiceDescription.DomainServiceType, out providerTypeDeclaration);

            if (providerTypeDeclaration != null)
            {
                providerTypeDeclaration.BaseTypes.Clear();
                providerTypeDeclaration.BaseTypes.Add(
                    new CodeTypeReference(AuthenticationCodeProcessor.AuthenticationDomainContextBaseName)
                    {
                        Options = CodeTypeReferenceOptions.GlobalReference
                    });
            }
        }
        private static bool IsValidMethodSignature(DomainServiceDescription description, DomainOperationEntry operationEntry, DomainOperation operation, out Exception error)
        {
            string methodName = operationEntry.Name;
            ReadOnlyCollection<DomainOperationParameter> parameters = operationEntry.Parameters;
            Type returnType = operationEntry.ReturnType;

            switch (operation)
            {
                case DomainOperation.Delete:
                case DomainOperation.Insert:
                case DomainOperation.Update:
                    {
                        // insert signature check: parameter length must be 1
                        if (parameters.Count != 1)
                        {
                            error = new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Resource.InvalidInsertUpdateDeleteMethod_IncorrectParameterLength, methodName));
                            return false;
                        }

                        // parameter must be by-value
                        if (!IsByVal(parameters[0]))
                        {
                            error = new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Resource.InvalidDomainOperationEntry_ParamMustBeByVal, methodName, parameters[0].Name));
                            return false;
                        }

                        if (!description._entityTypes.Contains(parameters[0].ParameterType))
                        {
                            error = new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Resource.InvalidDomainMethod_ParamMustBeEntity, parameters[0].Name, methodName));
                            return false;
                        }

                        break;
                    }
                case DomainOperation.Query:
                    {
                        // Ignore the optional "out count" parameter.
                        IEnumerable<DomainOperationParameter> queryParameters = parameters;
                        DomainOperationParameter lastParameter = queryParameters.LastOrDefault();
                        if (lastParameter != null && lastParameter.IsOut)
                        {
                            queryParameters = queryParameters.Take(queryParameters.Count() - 1).ToArray();
                        }

                        foreach (DomainOperationParameter param in queryParameters)
                        {
                            if (!TypeUtility.IsPredefinedType(param.ParameterType))
                            {
                                error = new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Resource.InvalidDomainOperationEntry_ParamMustBeSimple, methodName, param.Name));
                                return false;
                            }
                        }

                        // Determine the entity Type and validate the return type
                        // (must return IEnumerable<T> or a singleton)
                        bool isSingleton = false;
                        Type entityType = DomainServiceDescription.GetQueryEntityReturnType(operationEntry, out isSingleton, out error);
                        if (error != null)
                        {
                            return false;
                        }

                        // validate the entity Type
                        if (entityType == null || !description._entityTypes.Contains(entityType))
                        {
                            string errorMessage;
                            if (!IsValidEntityType(entityType, out errorMessage))
                            {
                                error = new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Resource.Invalid_Entity_Type, entityType.Name, errorMessage));
                                return false;
                            }
                        }

                        // Only IEnumerable<T> returning query methods can be marked composable
                        if (isSingleton && ((QueryAttribute)operationEntry.OperationAttribute).IsComposable)
                        {
                            throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Resource.DomainServiceDescription_SingletonQueryMethodCannotCompose, methodName, returnType));
                        }

                        break;
                    }
                case DomainOperation.Custom:
                    {
                        // check that the method signature is conforming to our expectations (Entity, one or more of pre-defined types)
                        if (parameters.Count == 0)
                        {
                            error = new InvalidOperationException(Resource.InvalidCustomMethod_MethodCannotBeParameterless);
                            return false;
                        }
                        bool first = true;
                        foreach (DomainOperationParameter param in parameters)
                        {
                            if (first)
                            {
                                // if first parameter, ensure that its type is one of the Entity types associated with CRUD.
                                if (!description._entityTypes.Contains(param.ParameterType))
                                {
                                    error = new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Resource.InvalidDomainMethod_ParamMustBeEntity, param.Name, methodName));
                                    return false;
                                }
                                first = false;
                            }
                            else if (!TypeUtility.IsPredefinedType(param.ParameterType) && !TypeUtility.IsSupportedComplexType(param.ParameterType))
                            {
                                error = new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Resource.InvalidDomainOperationEntry_ParamMustBeSimple, methodName, param.Name));
                                return false;
                            }
                        }
                        break;
                    }
                case DomainOperation.Invoke:
                    {
                        foreach (DomainOperationParameter param in parameters)
                        {
                            // parameter Type must be one of the predefined types, a supported complex type, an entity or collection of entities
                            if (!description._entityTypes.Contains(param.ParameterType) && !TypeUtility.IsPredefinedType(param.ParameterType) && !TypeUtility.IsSupportedComplexType(param.ParameterType))
                            {
                                // see if the parameter type is a supported collection of entities
                                Type elementType = TypeUtility.GetElementType(param.ParameterType);
                                bool isEntityCollection = description._entityTypes.Contains(elementType) && TypeUtility.IsSupportedCollectionType(param.ParameterType);
                                if (!isEntityCollection)
                                {
                                    error = new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Resource.InvalidInvokeOperation_ParameterType, methodName));
                                    return false;
                                }
                            }
                        }

                        // return Type must be one of the predefined types, an entity or collection of entities
                        if (returnType != typeof(void) && !description._entityTypes.Contains(returnType) && !TypeUtility.IsPredefinedType(returnType) && !TypeUtility.IsSupportedComplexType(returnType))
                        {
                            // see if the return is a supported collection of entities
                            Type elementType = TypeUtility.GetElementType(returnType);
                            bool isEntityCollection = description._entityTypes.Contains(elementType) && TypeUtility.IsSupportedCollectionType(returnType);
                            if (!isEntityCollection)
                            {
                                error = new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Resource.InvalidInvokeOperation_ReturnType, methodName));
                                return false;
                            }
                        }
                        break;
                    }
            }

            if (operation != DomainOperation.Invoke && operation != DomainOperation.Query)
            {
                // return type should be void for other domain operations except invoke operations
                if (returnType != typeof(void) || operationEntry.IsTaskAsync)
                {
                    error = new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Resource.InvalidDomainOperationEntry_NonQueryMustReturnVoid, methodName));
                    return false;
                }
            }

            error = null;
            return true;
        }
 private static void ValidateMethodSignature(DomainServiceDescription description, DomainOperationEntry method)
 {
     Exception error;
     if (!IsValidMethodSignature(description, method, method.Operation, out error))
     {
         throw error;
     }
 }
        /// <summary>
        /// Populates a contract description from a domain service description.
        /// </summary>
        /// <param name="contractDesc">Contract description to populate.</param>
        /// <param name="domainServiceDescription">Domain service description.</param>
        private void LoadContractDescription(ContractDescription contractDesc, DomainServiceDescription domainServiceDescription)
        {
            OperationDescription operationDesc;
            Debug.Assert(this.domainDataServiceMetadata != null, "this.domainDataServiceMetadata != null");

            // Create contract operations by inferring them from the [Query] & [Invoke] methods on the domain service.
            foreach (DomainOperationEntry operation in domainServiceDescription.DomainOperationEntries)
            {
                if (this.domainDataServiceMetadata.Sets.ContainsKey(operation.Name) || this.domainDataServiceMetadata.ServiceOperations.ContainsKey(operation.Name))
                {
                    switch (operation.Operation)
                    {
                        case DomainOperation.Query:
                            operationDesc = ODataEndpointFactory.CreateQueryOperationDescription(contractDesc, operation);
                            Type queryOperationType = typeof(DomainDataServiceQueryOperationBehavior<>).MakeGenericType(operation.AssociatedType);
                            // Add as first behavior such that our operation invoker is the first in the chain.
                            operationDesc.Behaviors.Insert(0, (IOperationBehavior)Activator.CreateInstance(queryOperationType, operation));
                            contractDesc.Operations.Add(operationDesc);
                            break;
                        case DomainOperation.Invoke:
                            operationDesc = ODataEndpointFactory.CreateOperationDescription(contractDesc, operation);
                            // Add as first behavior such that our operation invoker is the first in the chain.
                            operationDesc.Behaviors.Insert(0, new DomainDataServiceInvokeOperationBehavior(operation));
                            contractDesc.Operations.Add(operationDesc);
                            break;
                        default:
                            break;
                    }
                }
            }
        }
 /// <summary>
 /// Default constructor.
 /// </summary>
 /// <param name="description">A description of the <see cref="DomainService"/> this type creates surrogates for.</param>
 /// <param name="exposedTypeToSurrogateMap">
 /// The map of known exposed types to surrogate types. This object is passed in externally for efficiency reasons. Its 
 /// contents won't change; the set is owned by this type.
 /// </param>
 /// <param name="surrogateTypes">
 /// The set of known surrogate types. This object is passed in externally for efficiency reasons. Its contents 
 /// won't change; the set is owned by this type.
 /// </param>
 public DomainServiceSerializationSurrogate(DomainServiceDescription description, Dictionary<Type, Tuple<Type, Func<object, object>>> exposedTypeToSurrogateMap, HashSet<Type> surrogateTypes)
 {
     this.description = description;
     this.exposedTypeToSurrogateMap = exposedTypeToSurrogateMap;
     this.surrogateTypes = surrogateTypes;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="ComplexTypeProxyGenerator"/> class.
 /// </summary>
 /// <param name="proxyGenerator">The client proxy generator against which this will generate code.  Cannot be null.</param>
 /// <param name="complexType">The complex type.  Cannot be null.</param>
 /// <param name="domainServiceDescription"><see cref="DomainServiceDescription"/> that exposes this complex type.</param>
 /// <param name="typeMapping">A dictionary of <see cref="DomainService"/> and related complex types that maps to their corresponding client-side <see cref="CodeTypeReference"/> representations.</param>
 public ComplexTypeProxyGenerator(CodeDomClientCodeGenerator proxyGenerator, Type complexType, DomainServiceDescription domainServiceDescription, IDictionary<Type, CodeTypeDeclaration> typeMapping)
     : base(proxyGenerator, complexType, typeMapping)
 {
     this._domainServiceDescription = domainServiceDescription;
 }
        /// <summary>
        /// Validates that the authentication service implements the <see cref="IAuthentication{T}"/> interface 
        /// naturally for use in codegen.
        /// </summary>
        /// <remarks>
        /// This check ensures no part of the interface was implemented explicitly.
        /// </remarks>
        /// <param name="authenticationServiceDescription">The domain service description for the type that implemented 
        /// the <see cref="IAuthentication{T}"/> interface.
        /// </param>
        /// <param name="genericIAuthenticationType">The generic version of <see cref="IAuthentication{T}"/> implemented
        /// by the service type of the <paramref name="authenticationServiceDescription"/>.
        /// </param>
        /// <exception cref="InvalidOperationException"> is thrown if the <see cref="IAuthentication{T}"/> interface
        /// is not correctly implemented.
        /// </exception>
        private static void CheckIAuthentication(DomainServiceDescription authenticationServiceDescription, out Type genericIAuthenticationType)
        {
            bool implementsLogin = false;
            bool implementsLogout = false;
            bool implementsGetUser = false;
            bool implementsUpdateUser = false;

            if (!typeof(IAuthentication<>).DefinitionIsAssignableFrom(authenticationServiceDescription.DomainServiceType, out genericIAuthenticationType))
            {
                throw new InvalidOperationException(Resources.ApplicationServices_MustBeIAuth);
            }

            Type userType = genericIAuthenticationType.GetGenericArguments()[0];

            foreach (DomainOperationEntry doe in authenticationServiceDescription.DomainOperationEntries)
            {
                switch (doe.Name)
                {
                    case "Login":
                        implementsLogin = AuthenticationCodeProcessor.CheckIAuthenticationLogin(doe, userType);
                        break;
                    case "Logout":
                        implementsLogout = AuthenticationCodeProcessor.CheckIAuthenticationLogout(doe, userType);
                        break;
                    case "GetUser":
                        implementsGetUser = AuthenticationCodeProcessor.CheckIAuthenticationGetUser(doe, userType);
                        break;
                    case "UpdateUser":
                        implementsUpdateUser = AuthenticationCodeProcessor.CheckIAuthenticationUpdateUser(doe, userType);
                        break;
                    default:
                        break;
                }
            }

            if (!implementsLogin || !implementsLogout || !implementsGetUser || !implementsUpdateUser)
            {
                throw new InvalidOperationException(string.Format(
                    CultureInfo.InstalledUICulture,
                    Resources.ApplicationServices_MustBeIAuthImpl,
                    authenticationServiceDescription.DomainServiceType.Name));
            }
        }
 public override void ProcessGeneratedCode(DomainServiceDescription domainServiceDescription, CodeCompileUnit codeCompileUnit, IDictionary<Type, CodeTypeDeclaration> typeMapping)
 {
     return;
 }
public virtual void GenerateDomainContextClass(DomainServiceDescription domainServiceDescription)
{

        
        #line default
        #line hidden
        
        #line 5 "c:\dd\Alex_AppFx\AppFx\RiaServices\Main\OpenRiaServices.DomainServices.Tools\Test\T4DomainServiceCodeGenerator\DomainContext.ttinclude"
this.Write("namespace ");

        
        #line default
        #line hidden
        
        #line 6 "c:\dd\Alex_AppFx\AppFx\RiaServices\Main\OpenRiaServices.DomainServices.Tools\Test\T4DomainServiceCodeGenerator\DomainContext.ttinclude"
this.Write(this.ToStringHelper.ToStringWithCulture(domainServiceDescription.DomainServiceType.Namespace));

        
        #line default
        #line hidden
        
        #line 6 "c:\dd\Alex_AppFx\AppFx\RiaServices\Main\OpenRiaServices.DomainServices.Tools\Test\T4DomainServiceCodeGenerator\DomainContext.ttinclude"
this.Write("\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using System.C" +
        "omponentModel;\r\n    using System.ComponentModel.DataAnnotations;\r\n    using Syst" +
        "em.Data;\r\n    using System.Linq;\r\n\r\n    public class ");

        
        #line default
        #line hidden
        
        #line 15 "c:\dd\Alex_AppFx\AppFx\RiaServices\Main\OpenRiaServices.DomainServices.Tools\Test\T4DomainServiceCodeGenerator\DomainContext.ttinclude"
this.Write(this.ToStringHelper.ToStringWithCulture(domainServiceDescription.DomainServiceType.Name));

        
        #line default
        #line hidden
        
        #line 15 "c:\dd\Alex_AppFx\AppFx\RiaServices\Main\OpenRiaServices.DomainServices.Tools\Test\T4DomainServiceCodeGenerator\DomainContext.ttinclude"
this.Write("Context : DomainContext\r\n    {\r\n    }\r\n}\r\n");

        
        #line default
        #line hidden
        
        #line 19 "c:\dd\Alex_AppFx\AppFx\RiaServices\Main\OpenRiaServices.DomainServices.Tools\Test\T4DomainServiceCodeGenerator\DomainContext.ttinclude"
 } 
 /// <summary>
 /// Initializes a new instance of the <see cref="DomainOperationEntryProxyGenerator"/> class.
 /// </summary>
 /// <param name="clientProxyGenerator">The client proxy generator against which this will generate code.  Cannot be null.</param>
 /// <param name="proxyClass">The class into which to inject the generated code</param>
 /// <param name="domainServiceDescription">The description for the DomainService we're generating for</param>
 public DomainOperationEntryProxyGenerator(CodeDomClientCodeGenerator clientProxyGenerator, CodeTypeDeclaration proxyClass, DomainServiceDescription domainServiceDescription)
     : base(clientProxyGenerator)
 {
     this._proxyClass = proxyClass;
     this._domainServiceDescription = domainServiceDescription;
 }
 /// <summary>
 /// Factory method used to create <see cref="DomainServiceDescription"/> based on the specified description.
 /// </summary>
 /// <param name="baseDescription">The base description.</param>
 /// <returns>A new description based on the base description.</returns>
 protected DomainServiceDescription CreateDescription(DomainServiceDescription baseDescription)
 {
     if (baseDescription == null)
     {
         throw new ArgumentNullException("baseDescription");
     }
     return new DomainServiceDescription(baseDescription);
 }