public void EntityFrameworkSupportedInProject_returns_false_for_Misc_project_if_not_allowed() { const string vsMiscFilesProjectUniqueName = "<MiscFiles>"; var monikerHelper = new MockDTE("anytarget", vsMiscFilesProjectUniqueName); Assert.False( VsUtils.EntityFrameworkSupportedInProject(monikerHelper.Project, monikerHelper.ServiceProvider, allowMiscProject: false)); }
protected virtual ModelGenerationExtensionContext CreateContext() { Debug.Assert(VsUtils.EntityFrameworkSupportedInProject(_project, PackageManager.Package, allowMiscProject: false)); var targetSchemaVersion = EdmUtils.GetEntityFrameworkVersion(_project, PackageManager.Package); return(new ModelGenerationExtensionContextImpl( _project, targetSchemaVersion, _currentXDocument, _fromDatabaseDocument, WizardKind)); }
protected override ModelGenerationExtensionContext CreateContext() { Debug.Assert(VsUtils.EntityFrameworkSupportedInProject(Project, PackageManager.Package, allowMiscProject: false)); var targetSchemaVersion = EdmUtils.GetEntityFrameworkVersion(Project, PackageManager.Package); return(new UpdateModelFromDatabaseExtensionContextImpl( Project, ProjectItem, targetSchemaVersion, CurrentDocument, FromDatabaseDocument, OriginalDocument, UpdateModelDocument)); }
// <summary> // Project retargeting event handler. // 1. Check the project type, return immediately if project is misc project or a project that does not support EF. // 2. Find all the EDMX files in the project. Skip Data Services edmx files and linked files. // 3. Sync all the namespaces based on the new target framework // </summary> public void RetargetFilesInProject() { var project = VSHelpers.GetProject(_hierarchy); if (project == null || !VsUtils.EntityFrameworkSupportedInProject(project, _serviceProvider, allowMiscProject: false)) { return; } var targetSchemaVersion = EdmUtils.GetEntityFrameworkVersion(project, _serviceProvider, useLatestIfNoEF: false); Debug.Assert(targetSchemaVersion != null, "schema version must not be null for projects that support EF"); var documentMap = new Dictionary <string, object>(); foreach (var vsFileInfo in GetEdmxFileInfos()) { try { var projectItem = VsUtils.GetProjectItem(_hierarchy, vsFileInfo.ItemId); // skip the process for astoria edmx file or a linked edmx file if (IsDataServicesEdmx(projectItem.get_FileNames(1)) || VsUtils.IsLinkProjectItem(projectItem)) { continue; } var doc = RetargetFile(vsFileInfo.Path, targetSchemaVersion); if (doc != null) { documentMap.Add(vsFileInfo.Path, doc); } } catch (Exception ex) { // TODO: When there is an exception; should we continue? VsUtils.LogStandardError( string.Format(CultureInfo.CurrentCulture, Resources.ErrorSynchingEdmxNamespaces, vsFileInfo.Path, ex.Message), vsFileInfo.Path, 0, 0); throw; } } WriteModifiedFiles(project, documentMap); }
/// <summary> /// Return true if the wizard engine is supported for the project. /// </summary> bool IDataSourceWizardEngine.CanWorkInProject(Project project) { if (project != null) { var projectKind = VsUtils.GetProjectKind(project); // Currently, only VB, C# and Web projects are supported. if (projectKind == VsUtils.ProjectKind.CSharp || projectKind == VsUtils.ProjectKind.Web || projectKind == VsUtils.ProjectKind.VB) { using (var serviceProvider = new ServiceProvider((IOleServiceProvider)project.DTE)) { return(VsUtils .EntityFrameworkSupportedInProject(project, serviceProvider, false)); } } } return(false); }
internal static bool TryGetBufferViaExtensions( ProjectItem projectItem, string fileContents, out string documentViaExtensions, out List <ExtensionError> errors) { var converters = EscherExtensionPointManager.LoadModelConversionExtensions(); var serializers = EscherExtensionPointManager.LoadModelTransformExtensions(); if (projectItem == null || !VsUtils.EntityFrameworkSupportedInProject(projectItem.ContainingProject, PackageManager.Package, allowMiscProject: false) || (serializers.Length == 0 && converters.Length == 0)) { errors = new List <ExtensionError>(); documentViaExtensions = ""; return(false); } return(TryGetBufferViaExtensions( PackageManager.Package, projectItem, fileContents, converters, serializers, out documentViaExtensions, out errors)); }
public void EntityFrameworkSupportedInProject_returns_true_for_applicable_projects() { var targets = new[] { ".NETFramework,Version=v4.0", ".NETFramework,Version=v3.5", ".NETFramework,Version=v4.5", }; foreach (var target in targets) { var monikerHelper = new MockDTE(target); Assert.True( VsUtils.EntityFrameworkSupportedInProject(monikerHelper.Project, monikerHelper.ServiceProvider, allowMiscProject: true)); Assert.True( VsUtils.EntityFrameworkSupportedInProject(monikerHelper.Project, monikerHelper.ServiceProvider, allowMiscProject: false)); } }
int IVsEditorFactoryNotify.NotifyItemAdded(uint grfEFN, IVsHierarchy pHier, uint itemid, string pszMkDocument) { object o; var hr = pHier.GetProperty(itemid, (int)__VSHPROPID.VSHPROPID_ExtObject, out o); if (NativeMethods.Succeeded(hr)) { var projectItem = o as ProjectItem; if (projectItem != null && VsUtils.EntityFrameworkSupportedInProject(projectItem.ContainingProject, ServiceProvider, allowMiscProject: false)) { if (EdmUtils.IsDataServicesEdmx(projectItem.get_FileNames(1))) { // if the EDMX has a data services node, don't add the SingleFileGenerator, etc. return(VSConstants.S_OK); } IOleServiceProvider oleSP; pHier.GetSite(out oleSP); using (var sp = new ServiceProvider(oleSP)) { var appType = VsUtils.GetApplicationType(sp, projectItem.ContainingProject); // set the project item properties SetProjectItemProperties(projectItem, appType); } if (grfEFN != (uint)__EFNFLAGS.EFN_ClonedFromTemplate) { // we're not adding from template i.e. Add Existing Item var referenceFileNames = GetReferencesFromTemplateForProject(projectItem.ContainingProject); AddMissingReferences(projectItem, referenceFileNames); AddBuildProvider(projectItem); } } } return(VSConstants.S_OK); }
public void EntityFrameworkSupportedInProject_returns_false_for_project_where_EF_cannot_be_used() { var targets = new[] { ".NETFramework,Version=v3.0", ".NETFramework,Version=v2.0", ".XBox,Version=v4.5", string.Empty, null }; foreach (var target in targets) { var monikerHelper = new MockDTE(target); Assert.False( VsUtils.EntityFrameworkSupportedInProject(monikerHelper.Project, monikerHelper.ServiceProvider, allowMiscProject: true)); Assert.False( VsUtils.EntityFrameworkSupportedInProject(monikerHelper.Project, monikerHelper.ServiceProvider, allowMiscProject: false)); } }
private string DispatchSaveToExtensions(string fileContents) { Debug.Assert(fileContents != null, "fileContents != null"); // see if any extensions want to participate in saving if (Hierarchy != null) { var serializers = EscherExtensionPointManager.LoadModelTransformExtensions(); var converters = EscherExtensionPointManager.LoadModelConversionExtensions(); var projectItem = VsUtils.GetProjectItem(Hierarchy, ItemId); if ((serializers.Length > 0 || converters.Length > 0) && projectItem != null && VsUtils.EntityFrameworkSupportedInProject( projectItem.ContainingProject, PackageManager.Package, allowMiscProject: false)) { return(DispatchSaveToExtensions(PackageManager.Package, projectItem, fileContents, converters, serializers)); } } return(fileContents); }
private void EnsureCanStartWizard(IServiceProvider serviceProvider) { // make sure we can access the data package if (serviceProvider.GetService(typeof(IVsDataConnectionManager)) == null) { VsUtils.ShowErrorDialog(Resources.LoadDataPackageError); throw new WizardCancelledException(); } // make sure that our package is loaded try { PackageManager.LoadEDMPackage(serviceProvider); } catch (Exception ex) { // an exception occurred loading our package, so raise an error dialog, and cancel the wizard var message = Resources.LoadOurPackageError; #if DEBUG message += " " + ex; #else message += " " + ex.Message; #endif VsUtils.ShowErrorDialog(message); throw new WizardCancelledException(Resources.LoadOurPackageError, ex); } if (!VsUtils.EntityFrameworkSupportedInProject( _activeSolutionProject, serviceProvider, allowMiscProject: false)) { VsUtils.ShowErrorDialog( string.Format( CultureInfo.CurrentCulture, Resources.EdmUtils_NotValidTargetFramework)); Marshal.ThrowExceptionForHR(VSConstants.E_ABORT); } }
internal override void DetermineIfArtifactIsVersionSafe() { // We want to move the user to the latest possible schemas - so if a user opens a v2 edmx // file in a project that has a reference to an EF assembly that can handle v3 schema we // won't display the model but will show a watermark saying "please upgrade your schema" // There are two exceptions to this rule: // - a user opens an edmx without a project (a.k.a. Misc project) in that case we always show // the model // - a user is targeting .NET Framework 4 and has references to both System.Data.Entity.dll // and EF6 EntityFramework.dll in which case we allow opening both v2 and v3 edmx files var project = GetProject(); Debug.Assert(project != null); IsVersionSafe = VsUtils.EntityFrameworkSupportedInProject(project, ServiceProvider, allowMiscProject: true) && VsUtils.SchemaVersionSupportedInProject(project, SchemaVersion, ServiceProvider); if (IsVersionSafe) { base.DetermineIfArtifactIsVersionSafe(); } }
public override PropertyDescriptorCollection GetProperties(Attribute[] attributes) { var baseProperties = base.GetProperties(attributes); // clear out dictionary, as we will rebuild it in this method _propertyDescriptorToOwner.Clear(); if (RunningInVS) { // we only dispatch to extensions when we are running in VS. This is because there is a dep on vS things like ProjectItem var el = WrappedItem as EFElement; Debug.Assert(el != null, "wrapped item is null"); if (el != null) { var currentSelectionOrNull = EscherExtensionPointManager.DetermineEntityDesignerSelection(el); if (currentSelectionOrNull != null) { var currentSelection = (EntityDesignerSelection)currentSelectionOrNull; Debug.Assert((int)currentSelection != 0, "unexpected value for current selection"); var extensions = EscherExtensionPointManager.LoadPropertyDescriptorExtensions(); if (extensions.Length > 0) { // Note that if the user adds an EDMX file to their project and chooses not to save the project file, // the project item below can be null; it won't even exist in the miscellaneous files project. var projectItem = VsUtils.GetProjectItemForDocument(el.Artifact.Uri.LocalPath, PackageManager.Package); if (projectItem != null && VsUtils.EntityFrameworkSupportedInProject( projectItem.ContainingProject, PackageManager.Package, allowMiscProject: false)) { var targetSchemaVersion = EdmUtils.GetEntityFrameworkVersion(projectItem.ContainingProject, PackageManager.Package); // Use MEF extensions to create "owner" objects that define new property descriptors to add into the property sheet. // TODO: We track 'visited factories' since have to load the App-DB contracts as well as the standard contracts, but // MEF also loads the standard contracts in addition to the App-DB contracts. Need to see if MEF can support // otherwise. var propDescriptorOwners = new List <Object>(); var visitedFactories = new HashSet <IEntityDesignerExtendedProperty>(); foreach (var ex in extensions) { if (((int)ex.Metadata.EntityDesignerSelection & (int)currentSelection) == (int)currentSelection) { // Continue processing this extension var factory = ex.Value; if (factory != null && !visitedFactories.Contains(factory)) { visitedFactories.Add(factory); try { var extensionContext = new PropertyExtensionContextImpl( EditingContext, projectItem, targetSchemaVersion, factory.GetType().Assembly.GetName().GetPublicKeyToken()); var xelem = el.XElement; var sem = el as StorageEntityModel; if (currentSelection == EntityDesignerSelection.StorageModelEntityContainer && sem != null) { xelem = sem.FirstEntityContainer.XElement; } var o = factory.CreateProperty(xelem, extensionContext); if (o != null) { propDescriptorOwners.Add(o); } } catch (Exception e) { var exceptionMessage = VsUtils.ConstructInnerExceptionErrorMessage(e); var errorMessage = String.Format( CultureInfo.CurrentCulture, Resources.Extensibility_ErrorOccurredDuringCallToExtension, factory.GetType().FullName, exceptionMessage); VsUtils.ShowErrorDialog(errorMessage); } } } } // // Create PropertyDescriptors over the new "owner" // foreach (var o in propDescriptorOwners) { var props = TypeDescriptor.GetProperties(o, attributes, false); foreach (PropertyDescriptor pd in props) { var reflectedPropertyDescriptor = new ReflectedPropertyDescriptor(EditingContext, pd, o); if (reflectedPropertyDescriptor.IsBrowsable) { if (_propertyDescriptorToOwner.ContainsKey(reflectedPropertyDescriptor)) { // handle degenerate error case where dictionary already contains key. This shouldn't happen, but this is here just to be safe. Debug.Fail("_propertyDescriptor2Owner table already contains entry"); _propertyDescriptorToOwner.Remove(reflectedPropertyDescriptor); } _propertyDescriptorToOwner.Add(reflectedPropertyDescriptor, o); baseProperties.Add(reflectedPropertyDescriptor); } } } } } } } } return(baseProperties); }
internal static bool TryGetBufferViaExtensions( IServiceProvider serviceProvider, ProjectItem projectItem, string fileContents, Lazy <IModelConversionExtension, IEntityDesignerConversionData>[] converters, Lazy <IModelTransformExtension>[] serializers, out string documentViaExtensions, out List <ExtensionError> errors) { Debug.Assert(serviceProvider != null, "serviceProvider != null"); Debug.Assert(projectItem != null, "projectItem != null"); Debug.Assert(VsUtils.EntityFrameworkSupportedInProject(projectItem.ContainingProject, serviceProvider, false)); Debug.Assert(serializers != null && converters != null, "extensions must not be null"); Debug.Assert(serializers.Any() || converters.Any(), "at least one extension expected"); errors = new List <ExtensionError>(); documentViaExtensions = ""; ModelConversionContextImpl conversionContext = null; ModelTransformContextImpl transformContext = null; try { var targetSchemaVersion = EdmUtils.GetEntityFrameworkVersion(projectItem.ContainingProject, serviceProvider); Debug.Assert(targetSchemaVersion != null, "should not get here for a Misc project"); // get the extension of the file being loaded (might not be EDMX); this API will include the preceding "." var filePath = projectItem.get_FileNames(1); var fileExtension = Path.GetExtension(filePath); XDocument originalDocument = null; // see if we are loading an EDMX file or not, and if we have any converters if (!string.Equals( fileExtension, EntityDesignArtifact.ExtensionEdmx, StringComparison.OrdinalIgnoreCase)) { conversionContext = new ModelConversionContextImpl( projectItem.ContainingProject, projectItem, new FileInfo(filePath), targetSchemaVersion, fileContents); // we aren't loading an EDMX file, so call the extensions who can process this file extension // when this finishes, then output should be a valid EDMX document VSArtifact.DispatchToConversionExtensions(converters, fileExtension, conversionContext, true); // we are done with the non-EDMX extensions so CurrentDocument will be a valid EDMX document // create the serialization context for further extensions to act on transformContext = new ModelTransformContextImpl( projectItem, targetSchemaVersion, conversionContext.CurrentDocument); } else { // we are loading an EDMX file, we can parse file contents into an XDocument try { originalDocument = XDocument.Parse(fileContents, LoadOptions.PreserveWhitespace); transformContext = new ModelTransformContextImpl( projectItem, targetSchemaVersion, originalDocument); } catch (XmlException) { // If there's an error here, don't do anything. We will want to gracefully step out of the extension loading // since the designer itself won't load. } } if (transformContext != null && originalDocument != null) { // now dispatch to those that want to work on EDMX files VSArtifact.DispatchToSerializationExtensions(serializers, transformContext, true); // TODO: this does not seem to be correct if severity is Message or Warning if (transformContext.Errors.Count == 0) { // see if any extension changed things. Note that we need to compare the serialization of // the XDocuments together since the original buffer may have different whitespace after creating the XDocument. // TODO: Why not use XNode.DeepEquals()? string newBufferContents; using (var currentDocWriter = new Utf8StringWriter()) { transformContext.CurrentDocument.Save(currentDocWriter, SaveOptions.None); newBufferContents = currentDocWriter.ToString(); } string originalBufferContents; using (var originalDocWriter = new Utf8StringWriter()) { originalDocument.Save(originalDocWriter, SaveOptions.None); originalBufferContents = originalDocWriter.ToString(); } if (!string.Equals(originalBufferContents, newBufferContents, StringComparison.Ordinal)) { documentViaExtensions = newBufferContents; return(true); } } else { errors.AddRange(transformContext.Errors); return(false); } } } finally { var errorList = ErrorListHelper.GetExtensionErrorList(serviceProvider); errorList.Clear(); // log any errors if (conversionContext != null && conversionContext.Errors.Count > 0) { ErrorListHelper.LogExtensionErrors(conversionContext.Errors, projectItem); } if (transformContext != null && transformContext.Errors.Count > 0) { ErrorListHelper.LogExtensionErrors(transformContext.Errors, projectItem); } } return(false); }