예제 #1
0
        public static Type GetDataWrapperType(DataTypeDescriptor dataTypeDescriptor)
        {
            Type wrapperType = TryGetWrapperType(dataTypeDescriptor.GetFullInterfaceName());

            if (wrapperType != null)
            {
                return(wrapperType);
            }

            lock (_compilationLock)
            {
                wrapperType = TryGetWrapperType(dataTypeDescriptor.GetFullInterfaceName());
                if (wrapperType != null)
                {
                    return(wrapperType);
                }

                var codeGenerationBuilder = new CodeGenerationBuilder("DataWrapper:" + dataTypeDescriptor.GetFullInterfaceName());

                DataWrapperCodeGenerator.AddDataWrapperClassCode(codeGenerationBuilder, dataTypeDescriptor);

                IEnumerable <Type> types = CodeGenerationManager.CompileRuntimeTempTypes(codeGenerationBuilder);

                return(types.Single());
            }
        }
예제 #2
0
        public CodeTypeDeclaration CreateClass()
        {
            var codeTypeDeclaration = new CodeTypeDeclaration(_entityBaseClassName)
            {
                IsClass        = true,
                TypeAttributes = TypeAttributes.Public | TypeAttributes.Abstract
            };

            codeTypeDeclaration.BaseTypes.Add(typeof(INotifyPropertyChanged));
            codeTypeDeclaration.BaseTypes.Add(typeof(INotifyPropertyChanging));
            codeTypeDeclaration.BaseTypes.Add(typeof(IEntity));
            codeTypeDeclaration.BaseTypes.Add(_dataTypeDescriptor.GetFullInterfaceName());

            codeTypeDeclaration.Members.Add(new CodeMemberField(new CodeTypeReference(typeof(DataSourceId).FullName), EntityClassesFieldNames.DataSourceIdFieldName));
            codeTypeDeclaration.Members.Add(new CodeMemberField(new CodeTypeReference(typeof(DataScopeIdentifier).FullName), EntityClassesFieldNames.DataSourceIdScopeFieldName)
            {
                Attributes = MemberAttributes.Family
            });
            codeTypeDeclaration.Members.Add(new CodeMemberField(new CodeTypeReference(typeof(CultureInfo).FullName), EntityClassesFieldNames.DataSourceIdCultureFieldName)
            {
                Attributes = MemberAttributes.Family
            });

            AddConstructor(codeTypeDeclaration);
            AddIEntityImplementation(codeTypeDeclaration);
            AddIDataSourceProperty(codeTypeDeclaration);

            AddProperties(codeTypeDeclaration);

            EntityCodeGeneratorHelper.AddPropertyChanging(codeTypeDeclaration);
            EntityCodeGeneratorHelper.AddPropertyChanged(codeTypeDeclaration);

            return(codeTypeDeclaration);
        }
예제 #3
0
        private static CodeTypeDeclaration CreateCodeTypeDeclaration(DataTypeDescriptor dataTypeDescriptor)
        {
            string interfaceTypeFullName = dataTypeDescriptor.GetFullInterfaceName();

            var debugDisplayText = $"Data wrapper for '{interfaceTypeFullName}'";

            foreach (var keyPropertyName in dataTypeDescriptor.KeyPropertyNames)
            {
                debugDisplayText += $", {keyPropertyName} = {{{keyPropertyName}}}";
            }

            var labelFieldName = dataTypeDescriptor.LabelFieldName;

            if (!string.IsNullOrEmpty(labelFieldName) && !dataTypeDescriptor.KeyPropertyNames.Contains(labelFieldName))
            {
                debugDisplayText += $", {labelFieldName} = {{{labelFieldName}}}";
            }

            IEnumerable <Tuple <string, Type, bool> > properties =
                dataTypeDescriptor.Fields.
                Select(f => new Tuple <string, Type, bool>(f.Name, f.InstanceType, f.IsReadOnly)).
                Concat(new[] { new Tuple <string, Type, bool>("DataSourceId", typeof(DataSourceId), true) });

            var declaration = new CodeTypeDeclaration
            {
                Name           = CreateWrapperClassName(interfaceTypeFullName),
                IsClass        = true,
                TypeAttributes = TypeAttributes.Public | TypeAttributes.Sealed
            };

            declaration.BaseTypes.Add(interfaceTypeFullName);
            declaration.BaseTypes.Add(typeof(IDataWrapper));
            declaration.CustomAttributes.AddRange(new[]
            {
                new CodeAttributeDeclaration(
                    new CodeTypeReference(typeof(EditorBrowsableAttribute)),
                    new CodeAttributeArgument(
                        new CodeFieldReferenceExpression(
                            new CodeTypeReferenceExpression(typeof(EditorBrowsableState)),
                            EditorBrowsableState.Never.ToString()
                            )
                        )
                    ),
                new CodeAttributeDeclaration(
                    new CodeTypeReference(typeof(DebuggerDisplayAttribute)),
                    new CodeAttributeArgument(
                        new CodePrimitiveExpression(debugDisplayText)
                        )
                    )
            });

            declaration.Members.Add(new CodeMemberField(interfaceTypeFullName, WrappedObjectName));

            AddConstructor(declaration, interfaceTypeFullName);
            AddInterfaceProperties(declaration, properties);

            AddMethods(declaration, properties);

            return(declaration);
        }
예제 #4
0
        /// <summary>
        /// This method will return type given by the dataTypeDescriptor.
        /// If the data type does not exist, one will be dynamically
        /// runtime code generated.
        /// </summary>
        /// <param name="dataTypeDescriptor"></param>
        /// <param name="forceReCompilation">If this is true a new type will be compiled regardless if one already exists.</param>
        /// <returns></returns>
        public static Type GetType(DataTypeDescriptor dataTypeDescriptor, bool forceReCompilation = false)
        {
            bool codeGenerationNeeded;

            Type type = TryGetType(dataTypeDescriptor, forceReCompilation, out codeGenerationNeeded);

            if (type != null)
            {
                return(type);
            }

            if (codeGenerationNeeded)
            {
                lock (_lock)
                {
                    type = TypeManager.TryGetType(dataTypeDescriptor.GetFullInterfaceName());
                    if (type != null)
                    {
                        return(type);
                    }

                    var codeGenerationBuilder = new CodeGenerationBuilder("DataInterface: " + dataTypeDescriptor.Name);
                    InterfaceCodeGenerator.AddAssemblyReferences(codeGenerationBuilder, dataTypeDescriptor);
                    InterfaceCodeGenerator.AddInterfaceTypeCode(codeGenerationBuilder, dataTypeDescriptor);

                    IEnumerable <Type> types = CodeGenerationManager.CompileRuntimeTempTypes(codeGenerationBuilder);

                    return(types.Single());
                }
            }

            return(null);
        }
예제 #5
0
        /// <summary>
        /// This method will return the type of the empty data class type.
        /// If the type does not exist, one will be runtime code generated
        /// using the <paramref name="dataTypeDescriptor"/>.
        /// </summary>
        /// <param name="dataTypeDescriptor">
        /// The data type descriptor for the data type to get
        /// the empty class type for.
        /// </param>
        /// <param name="forceReCompilation">
        /// If this is true a new empty class will be
        /// compiled at runtime regardless if it exists or not.
        /// Use with caution!
        /// </param>
        /// <returns>The empty class type for the given data interface type.</returns>
        public static Type GetEmptyDataClassType(DataTypeDescriptor dataTypeDescriptor, bool forceReCompilation = false)
        {
            if (!string.IsNullOrEmpty(dataTypeDescriptor.BuildNewHandlerTypeName))
            {
                return(GetEmptyClassFromBuildNewHandler(dataTypeDescriptor));
            }


            if (forceReCompilation)
            {
                return(CreateEmptyDataClassType(dataTypeDescriptor));
            }

            Type interfaceType = TypeManager.TryGetType(dataTypeDescriptor.GetFullInterfaceName());

            string emptyClassFullName = EmptyDataClassCodeGenerator.GetEmptyClassTypeFullName(dataTypeDescriptor);
            Type   emptyClassType     = TypeManager.TryGetType(emptyClassFullName);

            bool isRecompileNeeded = true;

            if (interfaceType != null)
            {
                isRecompileNeeded = CodeGenerationManager.IsRecompileNeeded(interfaceType, new[] { emptyClassType });
            }

            if (isRecompileNeeded)
            {
                lock (_lock)
                {
                    interfaceType  = TypeManager.TryGetType(dataTypeDescriptor.GetFullInterfaceName());
                    emptyClassType = TypeManager.TryGetType(emptyClassFullName);
                    if (interfaceType != null)
                    {
                        isRecompileNeeded = CodeGenerationManager.IsRecompileNeeded(interfaceType, new[] { emptyClassType });
                    }

                    if (isRecompileNeeded)
                    {
                        emptyClassType = CreateEmptyDataClassType(dataTypeDescriptor);
                    }
                }
            }

            return(emptyClassType);
        }
예제 #6
0
        internal static Type TryGetType(DataTypeDescriptor dataTypeDescriptor, bool forceReCompilation, out bool codeGenerationNeeded)
        {
            Verify.ArgumentNotNull(dataTypeDescriptor, "dataTypeDescriptor");
            codeGenerationNeeded = false;

            Type type;

            if (!forceReCompilation)
            {
                type = TypeManager.TryGetType(dataTypeDescriptor.GetFullInterfaceName());
                if (type != null)
                {
                    return(type);
                }

                if (!dataTypeDescriptor.IsCodeGenerated)
                {
                    type = TypeManager.TryGetType(dataTypeDescriptor.TypeManagerTypeName);
                    if (type != null)
                    {
                        return(type);
                    }
                }
            }

            if (!dataTypeDescriptor.IsCodeGenerated)
            {
                return(null);
            }

            if (forceReCompilation)
            {
                type = TypeManager.TryGetType(dataTypeDescriptor.GetFullInterfaceName());
                if (type != null)
                {
                    return(type);
                }
            }

            codeGenerationNeeded = true;
            return(null);
        }
        private static CodeTypeDeclaration CreateCodeTypeDeclaration(DataTypeDescriptor dataTypeDescriptor)
        {
            string fullName = dataTypeDescriptor.GetFullInterfaceName();

            IEnumerable <Tuple <string, Type, bool> > properties =
                dataTypeDescriptor.Fields.
                Select(f => new Tuple <string, Type, bool>(f.Name, f.InstanceType, f.IsReadOnly)).
                Concat(new[] { new Tuple <string, Type, bool>("DataSourceId", typeof(DataSourceId), true) });

            return(CreateCodeTypeDeclaration(fullName, properties));
        }
        private static string GetTempFileName(DataTypeDescriptor typeDescriptor)
        {
            string folderPath = PathUtil.Resolve(GlobalSettingsFacade.GeneratedAssembliesDirectory);

            string filePath = Path.Combine(folderPath, typeDescriptor.GetFullInterfaceName() + ".cs");

            if (filePath.Length > 255)
            {
                filePath = Path.Combine(folderPath, typeDescriptor.DataTypeId + ".cs");
            }

            return(filePath);
        }
예제 #9
0
        /// <summary>
        /// Gets the runtime data type for the given data type id.
        /// In case of generated types, this call might result in a interface code compilation.
        /// </summary>
        /// <param name="dataTypeDescriptor">
        /// The DataTypeDescriptor for the data type.
        /// </param>
        /// <returns>Returns the data type. Never null.</returns>
        public static Type GetDataType(DataTypeDescriptor dataTypeDescriptor)
        {
            Verify.ArgumentNotNull(dataTypeDescriptor, "dataTypeDescriptor");

            Type loadedDataType = _LoadedDataTypes.FirstOrDefault(f => f.FullName == dataTypeDescriptor.GetFullInterfaceName());

            if (loadedDataType != null)
            {
                return(loadedDataType);
            }

            Type type = InterfaceCodeManager.GetType(dataTypeDescriptor);

            return(type);
        }
예제 #10
0
        private void AddInterfaceTypeProperty(CodeTypeDeclaration declaration)
        {
            CodeMemberProperty property = new CodeMemberProperty();

            property.Name       = "_InterfaceType";
            property.HasGet     = true;
            property.HasSet     = false;
            property.Type       = new CodeTypeReference(typeof(Type));
            property.Attributes = MemberAttributes.Public | MemberAttributes.Override;

            property.GetStatements.Add(new CodeMethodReturnStatement(
                                           new CodeTypeOfExpression(_dataTypeDescriptor.GetFullInterfaceName())
                                           ));


            declaration.Members.Add(property);
        }
예제 #11
0
        internal static string GenerateTableName(DataTypeDescriptor dataTypeDescriptor, DataScopeIdentifier dataScope, CultureInfo cultureInfo)
        {
            string tableName = dataTypeDescriptor.GetFullInterfaceName().Replace('.', '_');

            switch (dataScope.Name)
            {
            case DataScopeIdentifier.PublicName:
                break;

            case DataScopeIdentifier.AdministratedName:
                tableName += "_Unpublished";
                break;

            default:
                throw new InvalidOperationException("Unsupported data scope identifier: '{0}'".FormatWith(dataScope.Name));
            }

            if (!cultureInfo.Name.IsNullOrEmpty())
            {
                tableName += "_" + cultureInfo.Name.Replace('-', '_').Replace(' ', '_');
            }

            return(tableName);
        }
예제 #12
0
 internal static string GenerateTableName(DataTypeDescriptor dataTypeDescriptor)
 {
     return(dataTypeDescriptor.GetFullInterfaceName().Replace('.', '_'));
 }
        private void AddAddDataMethod(CodeTypeDeclaration declaration)
        {
            const string dataContextVariableName         = "dataContext";
            const string dataToAddVariableName           = "dataToAdd";
            const string dataProivderContextVariableName = "dataProivderContext";
            const string castedDataToAddVariableName     = "castedDataToAdd";
            const string entityClassVariableName         = "entity";


            CodeMemberMethod codeMethod = new CodeMemberMethod();

            codeMethod.Name       = "AddData";
            codeMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final;
            codeMethod.ReturnType = new CodeTypeReference(typeof(IData));
            codeMethod.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(ISqlDataContext)), dataContextVariableName));
            codeMethod.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(IData)), dataToAddVariableName));
            codeMethod.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(DataProviderContext)), dataProivderContextVariableName));


            codeMethod.Statements.Add(
                new CodeVariableDeclarationStatement(
                    new CodeTypeReference(_dataTypeDescriptor.GetFullInterfaceName()),
                    castedDataToAddVariableName,
                    new CodeCastExpression(
                        new CodeTypeReference(_dataTypeDescriptor.GetFullInterfaceName()),
                        new CodeVariableReferenceExpression(dataToAddVariableName)
                        )
                    ));


            codeMethod.Statements.Add(
                new CodeVariableDeclarationStatement(
                    new CodeTypeReference(_entityClassName),
                    entityClassVariableName,
                    new CodeObjectCreateExpression(
                        new CodeTypeReference(_entityClassName),
                        new CodeExpression[] { }
                        )
                    ));


            foreach (string propertyName in _dataTypeDescriptor.Fields.Select(f => f.Name))
            {
                codeMethod.Statements.Add(new CodeCommentStatement(string.Format("Interface property {0}", propertyName)));

                codeMethod.Statements.Add(
                    new CodeAssignStatement(
                        new CodePropertyReferenceExpression(
                            new CodeVariableReferenceExpression(entityClassVariableName),
                            propertyName
                            ),
                        new CodePropertyReferenceExpression(
                            new CodeVariableReferenceExpression(castedDataToAddVariableName),
                            propertyName
                            )
                        ));
            }


            codeMethod.Statements.Add(new CodeCommentStatement("Done with properties"));

            codeMethod.Statements.Add(
                new CodeExpressionStatement(
                    new CodeMethodInvokeExpression(
                        new CodeVariableReferenceExpression(dataContextVariableName),
                        "Add",
                        new CodeExpression[] {
                new CodeVariableReferenceExpression(entityClassVariableName),
                new CodePrimitiveExpression(_dataContextFieldName)
            }
                        )
                    ));


            codeMethod.Statements.Add(
                new CodeMethodReturnStatement(
                    new CodeVariableReferenceExpression(entityClassVariableName)
                    ));

            declaration.Members.Add(codeMethod);
        }
예제 #14
0
 internal static string MakeDataProviderHelperClassName(DataTypeDescriptor dataTypeDescriptor)
 {
     return(string.Format("{0}DataProviderHelper", dataTypeDescriptor.GetFullInterfaceName().Replace('.', '_').Replace('+', '_')));
 }
        public void AlterStore(UpdateDataTypeDescriptor updateDataTypeDescriptor, bool forceCompile)
        {
            XmlDataProviderDocumentCache.ClearCache();

            XmlProviderInterfaceConfigurationElement element = InterfaceConfigurationManipulator.Change(updateDataTypeDescriptor);

            if (forceCompile)
            {
                DataTypeDescriptor dataTypeDescriptor = updateDataTypeDescriptor.NewDataTypeDescriptor;

                Type dataProviderHelperType;
                Type dataIdClassType;
                bool typesExists = EnsureNeededTypes(dataTypeDescriptor, out dataProviderHelperType, out dataIdClassType, true);
                Verify.That(typesExists, "Could not find or code generated the type '{0}' or one of the needed helper types", dataTypeDescriptor.GetFullInterfaceName());

                var xmlDataTypeStoreDataScopes = new List <XmlDataTypeStoreDataScope>();
                foreach (DataScopeConfigurationElement dataScopeConfigurationElement in element.ConfigurationStores)
                {
                    var xmlDataTypeStoreDataScope = new XmlDataTypeStoreDataScope
                    {
                        DataScopeName = dataScopeConfigurationElement.DataScope,
                        CultureName   = dataScopeConfigurationElement.CultureName,
                        ElementName   = dataScopeConfigurationElement.ElementName,
                        Filename      = Path.Combine(_fileStoreDirectory, dataScopeConfigurationElement.Filename)
                    };

                    xmlDataTypeStoreDataScopes.Add(xmlDataTypeStoreDataScope);
                }

                var xmlDataTypeStoreCreator = new XmlDataTypeStoreCreator(_fileStoreDirectory);

                XmlDataTypeStore xmlDateTypeStore = xmlDataTypeStoreCreator.CreateStoreResult(dataTypeDescriptor, dataProviderHelperType, dataIdClassType, xmlDataTypeStoreDataScopes);

                Type interfaceType = DataTypeTypesManager.GetDataType(dataTypeDescriptor);

                UpdateDataTypeStore(dataTypeDescriptor, interfaceType, xmlDateTypeStore);
            }
        }
예제 #16
0
        public CodeTypeDeclaration CreateClass()
        {
            var debugDisplayText = $"SQL entity for '{_dataTypeDescriptor.GetFullInterfaceName()}', culture = '{_localeCultureName}', scope = '{_dataScopeIdentifierName}'";

            foreach (var keyPropertyName in _dataTypeDescriptor.KeyPropertyNames)
            {
                debugDisplayText += $", {keyPropertyName} = {{{keyPropertyName}}}";
            }

            var labelFieldName = _dataTypeDescriptor.LabelFieldName;

            if (!string.IsNullOrEmpty(labelFieldName) && !_dataTypeDescriptor.KeyPropertyNames.Contains(labelFieldName))
            {
                debugDisplayText += $", {labelFieldName} = {{{labelFieldName}}}";
            }

            var codeTypeDeclaration = new CodeTypeDeclaration(_entityClassName)
            {
                IsClass        = true,
                TypeAttributes = TypeAttributes.Public
            };

            codeTypeDeclaration.BaseTypes.Add(new CodeTypeReference(_entityBaseClassName));
            codeTypeDeclaration.CustomAttributes.AddRange(new []
            {
                new CodeAttributeDeclaration(
                    new CodeTypeReference(typeof(TableAttribute)),
                    new CodeAttributeArgument("Name", new CodePrimitiveExpression(_tableName))
                    ),
                new CodeAttributeDeclaration(
                    new CodeTypeReference(typeof(DebuggerDisplayAttribute)),
                    new CodeAttributeArgument(
                        new CodePrimitiveExpression(debugDisplayText)
                        )
                    )
            });


            string propertyName =
                typeof(DataScopeIdentifier).GetProperties(BindingFlags.Static | BindingFlags.Public).
                Where(f => f.Name.Equals(_dataScopeIdentifierName, StringComparison.OrdinalIgnoreCase)).
                Select(f => f.Name).
                Single();


            CodeMemberField constDataSourceIdCodeMemberField = new CodeMemberField(
                new CodeTypeReference(typeof(DataScopeIdentifier).FullName),
                EntityClassesFieldNames.DataSourceIdScopeConstFieldName
                );

            constDataSourceIdCodeMemberField.Attributes     = MemberAttributes.Static;
            constDataSourceIdCodeMemberField.InitExpression =
                new CodePropertyReferenceExpression(
                    new CodeTypeReferenceExpression(typeof(DataScopeIdentifier)),
                    propertyName
                    );
            codeTypeDeclaration.Members.Add(constDataSourceIdCodeMemberField);



            CodeMemberField constCultureCodeMemberField = new CodeMemberField(
                new CodeTypeReference(typeof(CultureInfo).FullName),
                EntityClassesFieldNames.DataSourceIdCultureConstFieldName
                );

            constCultureCodeMemberField.Attributes     = MemberAttributes.Static;
            constCultureCodeMemberField.InitExpression =
                new CodeObjectCreateExpression(
                    new CodeTypeReference(typeof(CultureInfo)),
                    new CodePrimitiveExpression(_localeCultureName)
                    );

            codeTypeDeclaration.Members.Add(constCultureCodeMemberField);

            AddEntityClassConstructor(codeTypeDeclaration);
            AddProperties(codeTypeDeclaration);

            return(codeTypeDeclaration);
        }
예제 #17
0
 private static string GetStoreName(DataTypeDescriptor dtd) => dtd.GetFullInterfaceName();
예제 #18
0
 private static string MakeNiceTypeFullName(DataTypeDescriptor dataTypeDescriptor)
 {
     return(dataTypeDescriptor.GetFullInterfaceName().Replace('.', '_').Replace('+', '_'));
 }
예제 #19
0
 internal static string MakeEntityBaseClassName(DataTypeDescriptor dataTypeDescriptor)
 {
     return(string.Format("{0}EntityBase", dataTypeDescriptor.GetFullInterfaceName().Replace('.', '_').Replace('+', '_')));
 }
예제 #20
0
 internal static string GetEmptyClassTypeFullName(DataTypeDescriptor dataTypeDescriptor)
 {
     return(NamespaceName + "." + CreateClassName(dataTypeDescriptor.GetFullInterfaceName()));
 }