Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial .NET Aspire integration prototype #585

Closed
wants to merge 28 commits into from

Conversation

jmezach
Copy link
Member

@jmezach jmezach commented Jul 18, 2024

As described in #584 we think there is value in providing some kind of integration between MSBuild.Sdk.SqlProj and .NET Aspire which would essentially allow a developer to spin up a SQL Server container and deploy a database project it. This could significantly enhance the inner loop.

This is a very early prototype of what such an integration could look like. A couple of observations:

  • For now I've just build everything into a test .NET Aspire project, but the code in Extensions.cs should probably move into a separate project (something like MSBuild.Sdk.SqlProj.Aspire maybe?)
  • Right now I'm getting a warning warning ASPIRE004: '../TestProject/TestProject.csproj' is referenced by an Aspire Host project, but it is not an executable. Did you mean to set IsAspireProjectResource="false"?. Setting that flag obviously resolves the warning, but then we can't get a hold of the project in Program.cs. Perhaps this should be a question to the .NET Aspire team.
  • I'm making a lot of assumptions about file paths to figure out the location of the .dacpac that needs to be deployed. It looks like .NET Aspire only provides us with the path to the .csproj but no other metadata from MSBuild that we can use (at least not that I've seen)
  • To deploy the .dacpac I'm using the DacFx package directly, so it is essentially part of the AppHost project. Not sure if that's the right way to go, but at least it works.

@ErikEJ @jeffrosenberg Thoughts?

@ErikEJ
Copy link
Collaborator

ErikEJ commented Jul 18, 2024

@davidfowl This is a really awesome inner loop experience for folks not using EF Core Migrations, but "databasemodel first" or even just Dapper / raw ADO.NET.

Who can help with the warning mentioned above?

@ErikEJ
Copy link
Collaborator

ErikEJ commented Jul 19, 2024

@pksorensen FYI! (and any comments / advice you may have)

@ErikEJ
Copy link
Collaborator

ErikEJ commented Jul 19, 2024

I was able to run and publish the .dacpac!

In order to run this locally in VS, I installed Docker Desktop and updated the .sln file to reference the TestProject.

I also added some robustness to Extension.cs to avoid some build warnings.

https://github.com/rr-wfm/MSBuild.Sdk.SqlProj/compare/feature/aspire-integration...ErikEJ:aspire-poc?expand=1

@jmezach
Copy link
Member Author

jmezach commented Jul 19, 2024

I was thinking that maybe the database project should be added as a custom resource, not as the built-in project resource, so you would get something like:

var builder = DistributedApplication.CreateBuilder(args);

var databaseProject = builder.AddDatabaseProject<Projects.TestProject>("db");

var sql = builder.AddSqlServer("sql")
                 .AddDatabase("test")
                 .WithDatabaseProject(databaseProject);

builder.Build().Run();

Then we can further customize the database project to include additional properties relevant for the deployment as well in the future and scope the WithDatabaseProject() method to only accept an IResourceBuilder<DatabaseProjectResource> and not just any database project. And we might be able to do some reading from the project file to figure out the right path to the .dacpac without hardcoding them.

@ErikEJ
Copy link
Collaborator

ErikEJ commented Jul 19, 2024

@jmezach Yes, that seems the way to go, and would probably also remove the ASPIRE004 warning

@jmezach
Copy link
Member Author

jmezach commented Jul 19, 2024

I'm afraid it won't fix that, since that warning is coming from the fact that I've added a reference to the project. If I remove the AddProject() call I still get the warning.

It might fix another issue I noticed when I tried to debug my AppHost project. It tried to run and attach a debugger to the database project, which obviously doesn't work.

@pksorensen
Copy link

I did similar for my database deploy projekt - the problem i ran into was that Aspire do not "create" databases, so the deploy part is responsible of creating the actually database if its missing. This was a gotcha for me that i had to work that out myself. Inspecting the code i dont see anything related to this but maybe bacpac takes care of it

@ErikEJ
Copy link
Collaborator

ErikEJ commented Jul 19, 2024

@pksorensen Thanks for chiming in! The dacpac magic takes care of creating the database and the objects inside it.

@pksorensen
Copy link

pksorensen commented Jul 19, 2024

The goal for me was to make it super easy for a new dev on the project to start the project. So stuff i was looking into was also to be able to run the aspire project (F5 experience) where it restores a database from a .bak file to be able to provide initial source data from some "restore point" to make it easier on dev to run/debug issues locally after a project has gone live. (a bit more advanced seed data that is able to fullfill usecases of the project for easier testing)

@ErikEJ
Copy link
Collaborator

ErikEJ commented Jul 19, 2024

@pksorensen You can also add a SQL MERGE script as a post deploy step to a .dacpac

@jmezach
Copy link
Member Author

jmezach commented Jul 19, 2024

I've done some more updates on this. First of all I've introduced the DatabaseProjectResource type as a first class citizen. This makes it show up on the dashboard as well and I've taken the liberty of pushing logs and updating the deployment status to it as well, see these screenshots:

Screenshot 2024-07-19 at 14 57 29
Screenshot 2024-07-19 at 14 57 34
Screenshot 2024-07-19 at 14 57 49

Now that I'm seeing this I'm wondering if we should perhaps inverse the relation ship between the SqlServer and the database project. So instead of this:

var builder = DistributedApplication.CreateBuilder(args);

var databaseProject = builder.AddDatabaseProject<Projects.TestProject>("db");

var sql = builder.AddSqlServer("sql")
                 .AddDatabase("test")
                 .WithDatabaseProject(databaseProject);

builder.Build().Run();

If we instead should do this:

var builder = DistributedApplication.CreateBuilder(args);

var sql = builder.AddSqlServer("sql")
                 .AddDatabase("test");

var databaseProject = builder.AddDatabaseProject<Projects.TestProject>("db");
                             .DeployTo(sql);

builder.Build().Run();

@ErikEJ
Copy link
Collaborator

ErikEJ commented Jul 19, 2024

Awesome. Would inverting the relationship change the UX in the dashboard?

@jmezach
Copy link
Member Author

jmezach commented Jul 19, 2024

No, I don't think so :).

@ErikEJ
Copy link
Collaborator

ErikEJ commented Jul 19, 2024

Agree on the updated fluent syntax!

@jmezach
Copy link
Member Author

jmezach commented Jul 19, 2024

I made that change now. It also makes the lifecycle hook a bit cleaner as now we only have to loop through the database projects, instead of going through all the SqlServerDatabaseResources and then all the annotation on that.

Have to say I'm pretty happy with how this has turned out so far and I think it can be a real game changer.

@ErikEJ
Copy link
Collaborator

ErikEJ commented Jul 19, 2024

There are some challenges with finding the .dacpac and ensure the project has been built... Is it possible to use the MsBuild SDK to load the project, or invoke a dotnet build and get some structured output from it?

@pksorensen
Copy link

I think the DeployTo is interesting. I agree that its easier when reading the code to understand what is going on, but i dont think i seen that in other aspire stuff. Feels like it been mosly "AddReference" and such.

I personally however prefer the .AddDatabase().WithDatabaseProject() (to me thats what i would expect from what i have seen on other aspire things).

I am trying to figure out why that "deployTo" does not feel right with me (read, that i dont feel that strongly about it) but i think its something related to that i feel that aspire describes the relationship between resources and not that we are deploying a project onto the database. Deploying is something that is generated from metatada from the relationship metadata in aspire.

Senarie could be that i want to use a database project in the database, but i dont want it to "deploy" it.

Just thinking out loud, i think this stuff is nice and i can use this as inpiration to my stuff to, thanks @ErikEJ for looping me in.

@jmezach
Copy link
Member Author

jmezach commented Jul 19, 2024

I tried using Microsoft.Build package to fetch the OutputPath from the project file by loading it, but then I got errors that it wasn't able to locate the Microsoft.NET.Sdk. Perhaps we could resolve that with https://github.com/microsoft/MSBuildLocator.

But I'm not sure whether it is worth it. I think we can safely assume that the project has already been build, since you need to add it as a reference to your AppHost project anyway. As for the "magic" strings, I think those can be assumed as well as we're setting these in the Sdk.props anyway. The only thing I can think of that might provide additional benefit is if we could read the deployment related properties from the project file and use them while deploying the .dacpac.

@ErikEJ
Copy link
Collaborator

ErikEJ commented Jul 19, 2024

"Senarie could be that i want to use a database project in the database, but i dont want it to "deploy" it"

You can not "use" a database project without publishing (deploying) it to a database.

Would PublishTo be easier to understand? (Yeah, naming is hard)

@jmezach
Copy link
Member Author

jmezach commented Jul 19, 2024

I guess PublishTo() would fit well with the current inner loop experience of running dotnet publish as well.

@ErikEJ
Copy link
Collaborator

ErikEJ commented Jul 19, 2024

@jmezach So we could read the publish properties from just .xml parsing?

@ErikEJ
Copy link
Collaborator

ErikEJ commented Jul 19, 2024

@jmezach "publish" is also what sqlpackage does

@jmezach
Copy link
Member Author

jmezach commented Jul 19, 2024

I think we might be able to get to the deployment properties by just using ProjectRootElement.Open(<path-to-project-file>) from Microsoft.Build package. This doesn't have to evaluate the entire project including all kinds of imports, it just reads the project file as is.

@jmezach
Copy link
Member Author

jmezach commented Jul 19, 2024

Okay, I gave up and just used MSBuild after all. Now I'm just evaluating the project and getting the TargetPath to figure out the path to the .dacpac file that needs to be deployed. Works like a charm on my machine at least.

Also renamed the DeployTo method to PublishTo which I think makes more sense.

@ErikEJ
Copy link
Collaborator

ErikEJ commented Jul 20, 2024

I will have another play with this this weekend.

Looks like the package name should be something that ends with .Aspire.Hosting

@ErikEJ
Copy link
Collaborator

ErikEJ commented Jul 21, 2024

Having looked more into Aspire and the configuration patterns, I think this is more natural (but an opinion from an actual Aspire expert would be helpful)

var builder = DistributedApplication.CreateBuilder(args);

var databaseProject = builder.AddDatabaseProject<Projects.TestProject>("db");

builder.AddSqlServer("sql")
        .AddDatabase("test")
        .WithDatabaseProject(databaseProject);

builder.Build().Run();
var builder = DistributedApplication.CreateBuilder(args);

builder.AddSqlServer("sql")
        .AddDatabase("test")
        .WithDacpac("myTestDacpac");

builder.Build().Run();

@jmezach
Copy link
Member Author

jmezach commented Jul 22, 2024

One problem I see with that proposal is that in the first case we add a resource to the DistributedApplicationBuilder while we don't do that in the latter. Also we're now back to adding things on top of the SqlServerDatabaseResource instead of the other way around.

I think having the "dacpac" as a resource in the model kind of makes sense, as we can also hook up logs and status to that resource. Perhaps we should use the "Data-Tier Application" moniker for this resource, so something like this?

Use case - Referenced project:

var builder = DistributedApplication.CreateBuilder(args);

var database = builder.AddSqlServer("sql")
        .AddDatabase("test");

var databaseProject = builder.AddDataTierApplication<Projects.TestProject>("db");
        .PublishTo(database);

builder.Build().Run();

Use case - Local .dacpac file:

var builder = DistributedApplication.CreateBuilder(args);

var database = builder.AddSqlServer("sql")
        .AddDatabase("test");

var databaseProject = builder.AddDataTierApplication("db", "/path/to/MyLocal.dacpac");
        .PublishTo(database);

builder.Build().Run();

@ErikEJ
Copy link
Collaborator

ErikEJ commented Jul 22, 2024

Perhaps we should use the "Data-Tier Application" moniker for this resource, so something like this?

Looks great!

@ErikEJ
Copy link
Collaborator

ErikEJ commented Jul 22, 2024

Did a quick spike on the other overload:

using Aspire.Hosting.Lifecycle;
using Microsoft.Build.Evaluation;
using Microsoft.Build.Locator;
using Microsoft.Extensions.Logging;
using Microsoft.SqlServer.Dac;

namespace Aspire.Hosting;

public static class Extensions
{
    public static IResourceBuilder<DatabaseProjectResource> AddDataTierApplication<TProject>(this IDistributedApplicationBuilder builder, string name)
        where TProject : IProjectMetadata, new()
    {
        var resource = CreateDatabaseProjectReference(name);

        return builder.AddResource(resource)
                      .WithAnnotation(new TProject());
    }

    public static IResourceBuilder<DatabaseProjectResource> AddDataTierApplication(this IDistributedApplicationBuilder builder, string name, string path)
    {
        var resource = CreateDatabaseProjectReference(name);

        return builder.AddResource(resource)
            .WithAnnotation(new TargetDacpacResourceAnnotation(path));
    }

    public static IResourceBuilder<DatabaseProjectResource> PublishTo(
    this IResourceBuilder<DatabaseProjectResource> builder, IResourceBuilder<SqlServerDatabaseResource> project)
    {
        builder.ApplicationBuilder.Services.TryAddLifecycleHook<DeployDatabaseProjectLifecycleHook>();
        builder.WithAnnotation(new TargetDatabaseResourceAnnotation(project.Resource.Name), ResourceAnnotationMutationBehavior.Replace);
        return builder;
    }

    public static IProjectMetadata? GetProjectMetadata(this DatabaseProjectResource resource)
    {
        return resource.Annotations.OfType<IProjectMetadata>().SingleOrDefault();
    }

    public static TargetDacpacResourceAnnotation? GetDacpacMetadata(this DatabaseProjectResource resource)
    {
        return resource.Annotations.OfType<TargetDacpacResourceAnnotation>().SingleOrDefault();
    }

    private static DatabaseProjectResource CreateDatabaseProjectReference(string name)
    {
        MSBuildLocator.RegisterInstance(MSBuildLocator.QueryVisualStudioInstances().OrderByDescending(
            instance => instance.Version).First());

        var resource = new DatabaseProjectResource(name);
        return resource;
    }
}

public sealed class DatabaseProjectResource(string name) : Resource(name)
{
    public string GetDacpacPath()
    {
        if (this.GetProjectMetadata() == null)
        {
            if (this.GetDacpacMetadata() is null)
            {
                throw new InvalidOperationException("Path to .dacpac file not specified.");
            }

            return this.GetDacpacMetadata()!.TargetDacpacPath;
        }
        else
        {
            var projectPath = this.GetProjectMetadata()!.ProjectPath;
            var project = new Project(projectPath);
            return project.GetPropertyValue("TargetPath");
        }
    }
}

public record TargetDacpacResourceAnnotation(string TargetDacpacPath) : IResourceAnnotation
{
}

@ErikEJ
Copy link
Collaborator

ErikEJ commented Jul 22, 2024

Adding this to Sdk.Props gets rid of the ASPIRE0004 error, but unsure if it has any other consequences (I cannot see any obvious):

  <PropertyGroup>
   ....
    <OutputType>Exe</OutputType>
  </PropertyGroup>

Signed-off-by: Jonathan Mezach <[email protected]>
Signed-off-by: Jonathan Mezach <[email protected]>
Signed-off-by: Jonathan Mezach <[email protected]>
@jmezach
Copy link
Member Author

jmezach commented Oct 11, 2024

Made some changes so that we try SqlTargetPath first. If that's not available we try TargetPath.

Also improved the error handling a bit.

@ErikEJ
Copy link
Collaborator

ErikEJ commented Oct 11, 2024

Publishing ready event would be a great addition, so we can support scenarios like Data Api Builder expecting the schema to be present at startup.

@ErikEJ
Copy link
Collaborator

ErikEJ commented Oct 12, 2024

@jmezach Can confirm .sqlprojx support works great!

@ErikEJ
Copy link
Collaborator

ErikEJ commented Oct 12, 2024

Just saw this: https://github.com/CommunityToolkit/Aspire

@jmezach
Copy link
Member Author

jmezach commented Oct 15, 2024

@ErikEJ Yeah, saw that too. Looks interesting. Not entirely sure though if it makes sense to move this to the toolkit. Or do you feel like it should be part of it?

@ErikEJ
Copy link
Collaborator

ErikEJ commented Oct 15, 2024

@jmezach There are pros and cons, but it looks like we will gain a lot of visibility in VS https://github.com/CommunityToolkit/Aspire/blob/main/docs/faq.md#finding-community-toolkit-integrations

Con: More formal constrains, but does not seem too bad.

@ErikEJ
Copy link
Collaborator

ErikEJ commented Oct 15, 2024

This is what the integration / visibility looks like:

image

@jmezach
Copy link
Member Author

jmezach commented Oct 15, 2024

This is what the integration / visibility looks like:

image

Those are just the "official" packages from the Aspire project I think?

@ErikEJ
Copy link
Collaborator

ErikEJ commented Oct 15, 2024

I think the view will also include packages from community according to the FAQ linked above..

@ErikEJ
Copy link
Collaborator

ErikEJ commented Oct 17, 2024

Full error message when trying to load a classic .sqlproj:

Microsoft.Build.Exceptions.InvalidProjectFileException
  HResult=0x80131500
  Message=The imported file "$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\SSDT\Microsoft.Data.Tools.Schema.SqlTasks.targets" does not exist and appears to be part of a Visual Studio component. This file may require MSBuild.exe in order to be imported successfully, and so may fail to build in the dotnet CLI.   C:\Code\Github\MSBuild.Sdk.SqlProj\test\Database\Database.sqlproj
  Source=Microsoft.Build

Wonder if we could do some probing given we have the path to the .sqlproj?

@ErikEJ
Copy link
Collaborator

ErikEJ commented Oct 17, 2024

I managed to add support for classic .sqlproj with the following changes:

using Aspire.Hosting;
using Aspire.Hosting.ApplicationModel;
using Microsoft.Build.Evaluation;
using Microsoft.Build.Exceptions;

namespace MSBuild.Sdk.SqlProj.Aspire;

public sealed class SqlProjectResource(string name) : Resource(name)
{
    public string GetDacpacPath()
    {
        var projectMetadata = Annotations.OfType<IProjectMetadata>().FirstOrDefault();
        if (projectMetadata != null)
        {
            try
            {
                var projectPath = projectMetadata.ProjectPath;
                using var projectCollection = new ProjectCollection();
                var project = projectCollection.LoadProject(projectPath);

                // .sqlprojx has a SqlTargetPath property, so try that first
                var targetPath = project.GetPropertyValue("SqlTargetPath");
                if (string.IsNullOrWhiteSpace(targetPath))
                {
                    targetPath = project.GetPropertyValue("TargetPath");
                }

                return targetPath;
            }
            catch (InvalidProjectFileException ex)
            {
                if (projectMetadata.ProjectPath.EndsWith(".sqlproj", StringComparison.OrdinalIgnoreCase))
                {
                    var dacpacPath = GetSqlprojDacpacPath(projectMetadata.ProjectPath);

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

                throw new InvalidOperationException($"Failed to load SQL Server Database project file {projectMetadata.ProjectPath}.", ex);
            }
        }

        var dacpacMetadata = Annotations.OfType<DacpacMetadataAnnotation>().FirstOrDefault();
        if (dacpacMetadata != null)
        {
            return dacpacMetadata.DacpacPath;
        }

        throw new InvalidOperationException($"Unable to locate SQL Server Database project package for resource {Name}.");
    }

    private string? GetSqlprojDacpacPath(string projectPath)
    {
        var directory = Path.GetDirectoryName(projectPath);

        if (directory == null)
        {
            return null;
        }

        var searchPath = Path.Combine(directory, "bin\\debug");

        var file = FindFile(searchPath);

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

        searchPath = Path.Combine(directory, "bin\\release");

        return FindFile(searchPath);
    }

    private static string? FindFile(string searchPath)
    {
        if (!Directory.Exists(searchPath))
        {
            return null;
        }

        var files = Directory.GetFiles(searchPath, "*.dacpac", SearchOption.AllDirectories)
            .Where(f => !f.EndsWith("\\msdb.dacpac", StringComparison.OrdinalIgnoreCase)
                && !f.EndsWith("\\master.dacpac", StringComparison.OrdinalIgnoreCase))
            .ToList();

        if (files.Count == 1)
        {
            return files[0];
        }

        return null;
    }
}

Signed-off-by: Jonathan Mezach <[email protected]>
@jmezach
Copy link
Member Author

jmezach commented Oct 18, 2024

I've now added publishing of an event when we're done deploying the .dacpac so that other resources can wait on that. As an example I've added a container to the TestAspireHost project that waits for the completion of the SQL project resource. This results in the container being started after the SQL project has successfully published to the SQL container. It then fails to start of course because it is bogus, but I think you get the idea :).

Signed-off-by: Jonathan Mezach <[email protected]>
Signed-off-by: Jonathan Mezach <[email protected]>
@jmezach
Copy link
Member Author

jmezach commented Oct 18, 2024

Also added a redeploy command that looks like this:

Screenshot 2024-10-18 at 16 12 57

It is only available when the SQL project has finished deploying successfully at least once. When clicking redeploy it will go through the same flow again. Can be really useful I think during development.

@ErikEJ
Copy link
Collaborator

ErikEJ commented Oct 19, 2024

Cool, love the redeploy, very useful. And the eventing makes scenarios like Data Api Builder so simple! (In particular when a Data Api Builder hosting component is also available)

https://github.com/JerryNixon/aspire-sqlserver/blob/main/202407-AspireDay/AspireDay.AppHost/Program.cs

@ErikEJ
Copy link
Collaborator

ErikEJ commented Nov 5, 2024

I have just confirmed that project discovery also works with the new .sqlproj projects supported by Azure Data Studio / VS Code

@jmezach
Copy link
Member Author

jmezach commented Nov 5, 2024

Not entirely sure what you mean with that ;).

@ErikEJ
Copy link
Collaborator

ErikEJ commented Nov 5, 2024

@jmezach There are currently multiple project types to build .dacpacs. Azure Data Studio and VS Code mssql extension support a project type with a .sqlproj extension that is the same as .sqlprojx (preview) in Visual Studio.

The Aspire integration can load this project type.

@kzryzstof
Copy link

Is this a known problem that the package fails if the .net SDK 8.0.403 is used?

However it seems to work properly with the SDK 8.0.204. This package is very useful :)

Here is the error that I got:

Microsoft.Build.Exceptions.InvalidProjectFileException: Invalid static method invocation syntax: "[MSBuild]::SubstringByAsciiChars($(MSBuildProjectFile), 0, 8)". Method '[MSBuild]::SubstringByAsciiChars' not found. Static method invocation should be of the form: $([FullTypeName]::Method()), e.g. $([System.IO.Path]::Combine(a, b)). Check that all parameters are defined, are of the correct type, and are specified in the right order. /usr/local/share/dotnet/sdk/8.0.403/Microsoft.Common.CurrentVersion.targets at Microsoft.Build.Shared.ProjectErrorUtilities.ThrowInvalidProject(String errorSubCategoryResourceName, IElementLocation elementLocation, String resourceName, Object[] args) at Microsoft.Build.Shared.ProjectErrorUtilities.ThrowInvalidProject[T1,T2](IElementLocation elementLocation, String resourceName, T1 arg0, T2 arg1) at Microsoft.Build.Evaluation.Expander2.Function1.Execute(Object objectInstance, IPropertyProvider1 properties, ExpanderOptions options, IElementLocation elementLocation)
at Microsoft.Build.Evaluation.Expander2.PropertyExpander1.ExpandPropertyBody(String propertyBody, Object propertyValue, IPropertyProvider1 properties, ExpanderOptions options, IElementLocation elementLocation, UsedUninitializedProperties usedUninitializedProperties, IFileSystem fileSystem) at Microsoft.Build.Evaluation.Expander2.PropertyExpander1.ExpandPropertiesLeaveTypedAndEscaped(String expression, IPropertyProvider1 properties, ExpanderOptions options, IElementLocation elementLocation, UsedUninitializedProperties usedUninitializedProperties, IFileSystem fileSystem, LoggingContext loggingContext)
at Microsoft.Build.Evaluation.Expander2.PropertyExpander1.ExpandPropertiesLeaveEscaped(String expression, IPropertyProvider1 properties, ExpanderOptions options, IElementLocation elementLocation, UsedUninitializedProperties usedUninitializedProperties, IFileSystem fileSystem, LoggingContext loggingContext) at Microsoft.Build.Evaluation.Expander2.ExpandIntoStringLeaveEscaped(String expression, ExpanderOptions options, IElementLocation elementLocation, LoggingContext loggingContext)
at Microsoft.Build.Evaluation.Evaluator4.EvaluatePropertyElement(ProjectPropertyElement propertyElement) at Microsoft.Build.Evaluation.Evaluator4.EvaluatePropertyGroupElement(ProjectPropertyGroupElement propertyGroupElement)
at Microsoft.Build.Evaluation.Evaluator4.PerformDepthFirstPass(ProjectRootElement currentProjectOrImport) at Microsoft.Build.Evaluation.Evaluator4.EvaluateImportElement(String directoryOfImportingFile, ProjectImportElement importElement)
at Microsoft.Build.Evaluation.Evaluator4.PerformDepthFirstPass(ProjectRootElement currentProjectOrImport) at Microsoft.Build.Evaluation.Evaluator4.EvaluateImportElement(String directoryOfImportingFile, ProjectImportElement importElement)
at Microsoft.Build.Evaluation.Evaluator4.PerformDepthFirstPass(ProjectRootElement currentProjectOrImport) at Microsoft.Build.Evaluation.Evaluator4.EvaluateImportElement(String directoryOfImportingFile, ProjectImportElement importElement)
at Microsoft.Build.Evaluation.Evaluator4.PerformDepthFirstPass(ProjectRootElement currentProjectOrImport) at Microsoft.Build.Evaluation.Evaluator4.EvaluateImportElement(String directoryOfImportingFile, ProjectImportElement importElement)
at Microsoft.Build.Evaluation.Evaluator4.PerformDepthFirstPass(ProjectRootElement currentProjectOrImport) at Microsoft.Build.Evaluation.Evaluator4.EvaluateImportElement(String directoryOfImportingFile, ProjectImportElement importElement)
at Microsoft.Build.Evaluation.Evaluator4.PerformDepthFirstPass(ProjectRootElement currentProjectOrImport) at Microsoft.Build.Evaluation.Evaluator4.EvaluateImportElement(String directoryOfImportingFile, ProjectImportElement importElement)
at Microsoft.Build.Evaluation.Evaluator4.PerformDepthFirstPass(ProjectRootElement currentProjectOrImport) at Microsoft.Build.Evaluation.Evaluator4.Evaluate()
at Microsoft.Build.Evaluation.Evaluator4.Evaluate(IEvaluatorData4 data, Project project, ProjectRootElement root, ProjectLoadSettings loadSettings, Int32 maxNodeCount, PropertyDictionary1 environmentProperties, ILoggingService loggingService, IItemFactory2 itemFactory, IToolsetProvider toolsetProvider, IDirectoryCacheFactory directoryCacheFactory, ProjectRootElementCacheBase projectRootElementCache, BuildEventContext buildEventContext, ISdkResolverService sdkResolverService, Int32 submissionId, EvaluationContext evaluationContext, Boolean interactive)
at Microsoft.Build.Evaluation.Project.ProjectImpl.Reevaluate(ILoggingService loggingServiceForEvaluation, ProjectLoadSettings loadSettings, EvaluationContext evaluationContext)
at Microsoft.Build.Evaluation.Project.ProjectImpl.ReevaluateIfNecessary(ILoggingService loggingServiceForEvaluation, ProjectLoadSettings loadSettings, EvaluationContext evaluationContext)
at Microsoft.Build.Evaluation.Project.ProjectImpl.ReevaluateIfNecessary(ILoggingService loggingServiceForEvaluation, EvaluationContext evaluationContext)
at Microsoft.Build.Evaluation.Project.ProjectImpl.ReevaluateIfNecessary(EvaluationContext evaluationContext)
at Microsoft.Build.Evaluation.Project.ProjectImpl.Initialize(IDictionary2 globalProperties, String toolsVersion, String subToolsetVersion, ProjectLoadSettings loadSettings, EvaluationContext evaluationContext, Boolean interactive) at Microsoft.Build.Evaluation.Project..ctor(String projectFile, IDictionary2 globalProperties, String toolsVersion, String subToolsetVersion, ProjectCollection projectCollection, ProjectLoadSettings loadSettings, EvaluationContext evaluationContext, IDirectoryCacheFactory directoryCacheFactory, Boolean interactive)
at Microsoft.Build.Evaluation.Project..ctor(String projectFile, IDictionary2 globalProperties, String toolsVersion, String subToolsetVersion, ProjectCollection projectCollection, ProjectLoadSettings loadSettings) at Microsoft.Build.Evaluation.Project..ctor(String projectFile, IDictionary2 globalProperties, String toolsVersion, ProjectCollection projectCollection, ProjectLoadSettings loadSettings)
at Microsoft.Build.Evaluation.Project..ctor(String projectFile, IDictionary2 globalProperties, String toolsVersion, ProjectCollection projectCollection) at Microsoft.Build.Evaluation.Project..ctor(String projectFile, IDictionary2 globalProperties, String toolsVersion)
at Microsoft.Build.Evaluation.Project..ctor(String projectFile)
at MSBuild.Sdk.SqlProj.Aspire.SqlProjectResource.GetDacpacPath() in //src/MSBuild.Sdk.SqlProj.Aspire/SqlProjectResource.cs:line 15
at MSBuild.Sdk.SqlProj.Aspire.PublishSqlProjectLifecycleHook.AfterResourcesCreatedAsync(DistributedApplicationModel application, CancellationToken cancellationToken) in /
/src/MSBuild.Sdk.SqlProj.Aspire/PublishSqlProjectLifecycleHook.cs:line 26
at Aspire.Hosting.Dcp.ApplicationExecutor.RunApplicationAsync(CancellationToken cancellationToken) in //src/Aspire.Hosting/Dcp/ApplicationExecutor.cs:line 141
at Aspire.Hosting.Dcp.DcpHostService.StartAsync(CancellationToken cancellationToken) in /
/src/Aspire.Hosting/Dcp/DcpHostService.cs:line 70
at Microsoft.Extensions.Hosting.Internal.Host.b__15_1(IHostedService service, CancellationToken token)
at Microsoft.Extensions.Hosting.Internal.Host.ForeachService[T](IEnumerable1 services, CancellationToken token, Boolean concurrent, Boolean abortOnFirstException, List1 exceptions, Func3 operation) at Microsoft.Extensions.Hosting.Internal.Host.StartAsync(CancellationToken cancellationToken) at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token) at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token) at Aspire.Hosting.DistributedApplication.RunAsync(CancellationToken cancellationToken) in /_/src/Aspire.Hosting/DistributedApplication.cs:line 311 at Program.<Main>$(String[] args) in

@ErikEJ
Copy link
Collaborator

ErikEJ commented Nov 11, 2024

@kzryzstof See this: #585 (comment) - do you have a preview SDK installed? Try a global.json file.

@kzryzstof
Copy link

kzryzstof commented Nov 11, 2024

@ErikEJ So I added the global.json file as suggested and chose the 8.0.403 SDK (not a preview). It still failed with the same error :(

All my projects are running .net8 (8.2.2 for Aspire).

Rider configuration
Screenshot 2024-11-11 at 9 59 35 AM

Global.json
Screenshot 2024-11-11 at 9 59 57 AM

Teh error
Screenshot 2024-11-11 at 10 00 39 AM

@ErikEJ
Copy link
Collaborator

ErikEJ commented Nov 11, 2024

@jmezach has a PR approved in the official Aspire Community Toolkit repo for Aspire 9, which will be published very soon.

Suggest you wait for that, the current package will be deprecated very soon.

@jmezach
Copy link
Member Author

jmezach commented Nov 13, 2024

We have decided that this integration is better served from the CommunityToolkit for Aspire rather than integrating it here. Thanks to everyone who has tried out this feature. We highly recommend migrating to CommunityToolkit version of this integration.

@jmezach jmezach closed this Nov 13, 2024
@jmezach jmezach deleted the feature/aspire-integration branch November 13, 2024 10:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants