Ejemplo n.º 1
0
        /// <summary>
        /// Generates the code for the domain service class.
        /// </summary>
        /// <param name="language">The language to use.</param>
        /// <param name="rootNamespace">The root namespace (VB).</param>
        /// <param name="optionalSuffix">If nonblank, the suffix to append to namespace and class names for testing</param>
        /// <returns>A value containing the generated source code and necessary references.</returns>
        public GeneratedCode GenerateMetadataClasses(string language, string rootNamespace, string optionalSuffix)
        {
            using (CodeGenContext codeGenContext = new CodeGenContext(language, rootNamespace))
            {
                bool generatedAnyCode = this.GenerateMetadataClasses(codeGenContext, optionalSuffix);
                if (generatedAnyCode)
                {
                    GeneratedCode generatedCode = codeGenContext.GenerateCode();
                    return(generatedCode);
                }
            }

            // Did not generate any code -- return empty tuple
            return(new GeneratedCode());
        }
Ejemplo n.º 2
0
        public void RunStarted(object automationObject,
                               Dictionary <string, string> replacementsDictionary,
                               WizardRunKind runKind, object[] customParams)
        {
            // This instance may be reused -- reinitialize each time
            this._project = null;

            this._dte2 = automationObject as DTE2;
            if (this._dte2 == null)
            {
                this.TerminateWizard(Resources.WizardError_No_DTE);
            }

            // Get active project.  Throws if null.
            Project project = this.ActiveProject;

            ITypeDiscoveryService typeDiscoveryService = this.GetTypeDiscoveryService(project);

            if (typeDiscoveryService == null)
            {
                this.TerminateWizard(Resources.BusinessLogicClass_Error_No_TypeDiscoveryService);
            }

            // Check if the project has a reference to the assembly that has DbDomainService, supporting DbContext.
            VSProject vsproj         = project.Object as VSProject;
            bool      allowDbContext = false;

            if (vsproj != null)
            {
                allowDbContext = vsproj.References.Cast <Reference>().Any(r => String.Equals(r.Name, BusinessLogicClassConstants.DbDomainServiceAssemblyShortName));
            }

            // Get the list of available ObjectContexts, DataContexts, and optionally DbContexts.
            bool foundDbContext           = false;
            IEnumerable <Type> candidates = this.GetCandidateTypes(typeDiscoveryService, allowDbContext, out foundDbContext);

            // Ensure the user entered a non-null file name
            string fileName = replacementsDictionary["$rootname$"];

            fileName = fileName.Trim();
            if (string.IsNullOrEmpty(fileName))
            {
                this.TerminateWizard(Resources.WizardError_Empty_Filename);
            }

            // Class name is file name minus extension.  Validate not empty.
            string className = Path.GetFileNameWithoutExtension(fileName);

            if (string.IsNullOrEmpty(className))
            {
                this.TerminateWizard(Resources.WizardError_Empty_Filename);
            }

            // We infer language from extension
            string extension = Path.GetExtension(fileName);
            bool   isVb      = extension.EndsWith("vb", StringComparison.OrdinalIgnoreCase);
            string language  = isVb ? "VB" : "C#";

            Property rootNamespaceProperty = project.Properties.Item("RootNamespace");
            string   namespaceName         = rootNamespaceProperty == null ? null : (string)(rootNamespaceProperty.Value);

            if (string.IsNullOrEmpty(namespaceName))
            {
                this.TerminateWizard(Resources.BusinessLogicClass_Error_No_RootNamespace);
            }

            // Extract VB root namespace for code gen.
            // If non-empty, it means we want to avoid generating namespaces that begin with it.
            string rootNamespace = isVb ? namespaceName : string.Empty;

            // Get the name of the assembly produced by the current project
            Property assemblyNameProperty = project.Properties.Item("AssemblyName");
            string   assemblyName         = assemblyNameProperty == null ? null : (string)(assemblyNameProperty.Value);

            if (string.IsNullOrEmpty(assemblyName))
            {
                this.TerminateWizard(Resources.BusinessLogicClass_Error_No_AssemblyName);
            }

            // We extract all the context types from the TypeDiscovery service and will pass
            // those to another AppDomain for analysis
            IEnumerable <Type> candidateTypes = candidates.Where(t => CodeGenUtilities.IsValidGenericTypeParam(t));

            // We need the project path for the ClientBuildManager source folder
            string projectPath = project.FullName;

            if (string.IsNullOrEmpty(projectPath))
            {
                this.TerminateWizard(Resources.BusinessLogicClass_No_Project_Path);
            }
            string projectDirectory = Path.GetDirectoryName(projectPath);

            try
            {
                IVsHelp help = this.GetService(typeof(IVsHelp)) as IVsHelp;
                // Strategy: we instantiate the contexts in another AppDomain so they can load the assembly outside of the current
                // Visual Studio root AppDomain.  The main reason for this is the ability to reopen the DSWizard onto modified
                // client assemblies and see modified types.  If they were loaded into the root AppDomain, we would not be able to
                // reload.  The BusinessLogicViewModel is IDisposable and controls the other AppDomain's lifetime.
                using (BusinessLogicViewModel businessLogicViewModel = new BusinessLogicViewModel(projectDirectory, className, language, rootNamespace, assemblyName, candidateTypes, help))
                {
                    businessLogicViewModel.ShowDbContextWarning = false; // foundDbContext; //Removed by CDB //TODO: remove commented out section

                    // Intercept exceptions to report to VS UI.
                    businessLogicViewModel.ExceptionHandler = delegate(Exception ex)
                    {
                        this.ShowError(ex.Message);
                        throw ex;
                    };

                    // Invoke the wizard UI now
                    this._dialog       = new BusinessLogicClassDialog();
                    this._dialog.Model = businessLogicViewModel;

                    IVsUIShell uiShell         = this.GetService(typeof(IVsUIShell)) as IVsUIShell;
                    IntPtr     dialogOwnerHwnd = default(IntPtr);
                    int        result          = uiShell.GetDialogOwnerHwnd(out dialogOwnerHwnd);
                    if (result == 0 && dialogOwnerHwnd != default(IntPtr))
                    {
                        WindowInteropHelper windowHelper = new WindowInteropHelper(this._dialog);
                        windowHelper.Owner = dialogOwnerHwnd;
                    }
                    this._dialog.ShowInTaskbar = false;

                    this._dialog.ShowDialog();
                    bool success = this._dialog.DialogResult.HasValue && this._dialog.DialogResult.Value;
                    this._dialog.Model = null;

                    // If user cancels dialog, cancel wizard
                    if (!success)
                    {
                        throw new WizardCancelledException();
                    }

                    // Capture some model state to we can dispose the contexts and models
                    ContextViewModel currentContext = businessLogicViewModel.CurrentContextViewModel;
                    this._isClientAccessEnabled  = currentContext != null && currentContext.IsClientAccessEnabled;
                    this._isODataEndpointEnabled = currentContext != null && currentContext.IsODataEndpointEnabled;

                    // Compute a namespace that includes folder names
                    namespaceName = this.ComputeNamespace();

                    // User said OK -- so let's generate the code
                    GeneratedCode generatedCode = businessLogicViewModel.GenerateBusinessLogicClass(namespaceName);

                    replacementsDictionary.Add("$generatedcode$", generatedCode.SourceCode);
                    this.AddReferences(generatedCode.References);
                    this._businessLogicCode = generatedCode;

                    // If user elected metadata classes, do that into a separate file
                    if (businessLogicViewModel.IsMetadataClassGenerationRequested)
                    {
                        // The null namespace asks to generate into the entity types own namespaces
                        GeneratedCode generatedMetadataCode = businessLogicViewModel.GenerateMetadataClasses(null /* optionalSuffix */);
                        replacementsDictionary.Add("$generatedmetadatacode$", generatedMetadataCode.SourceCode);
                        this.AddReferences(generatedMetadataCode.References);
                        this._generateMetadataFile = generatedMetadataCode.SourceCode.Length > 0;
                        this._metadataCode         = generatedMetadataCode;
                    }
                    else
                    {
                        this._generateMetadataFile = false;
                    }
                }
            }
            finally
            {
                this._dialog = null;
            }
        }