Open LeeMSilver opened 2 months ago
Below is a clearer implementation of DependencyInjectionCommand
.
[VisualStudioContribution]
internal class DependencyInjectionCommand : CommandLMS
{
public DependencyInjectionCommand(AsyncServiceProviderInjection<EnvDTE.DTE, EnvDTE80.DTE2> wDte,
AsyncServiceProviderInjection<AsyncPackage, IProjectSystemQueryService> wProject)
{
CmdDTEService = wDte;
CmdAsyncPackageService = wProject;
}
public override CommandConfiguration CommandConfiguration => new("DependencyInjection")
{
Shortcuts = [new CommandShortcutConfiguration(ModifierKey.LeftAlt, Key.X, ModifierKey.LeftAlt, Key.I)],
};
public override async Task ExecuteCommandAsync(IClientContext context, CancellationToken cancellationToken)
{
try
{
IProjectSystemQueryService queryService = await CmdAsyncPackageService.GetServiceAsync();
CmdProjectQueryableSpace = queryService.QueryableSpace;
}
catch (Exception wE)
{
handleCriticalError("ProjectWorkSpace", wE);
}
await CmdInvokeFirstCommandA(context, cancellationToken, "DependencyInjection");
// -----
static void handleCriticalError(String wDescription, Exception wException) =>
Status.EmitCriticalError($"""
Exception in {nameof(CmdInvokeFirstCommandA)} @{wDescription}
--Exception info--
{wException}
"""
);
}
}
Ignore all the DTE
stuff - that seems to be working ok.
public static AsyncServiceProviderInjection<AsyncPackage, IProjectSystemQueryService> CmdAsyncPackageService { get; set; }
is declared in a different file.
In ExecuteCommandAsync
at IProjectSystemQueryService queryService = await CmdAsyncPackageService.GetServiceAsync();
the following error is raised: Microsoft.VisualStudio.Shell.ServiceUnavailableException: The AsyncPackage service is unavailable.
The exception wE
follows:
Microsoft.VisualStudio.Shell.ServiceUnavailableException: The AsyncPackage service is unavailable.
at Microsoft.VisualStudio.Extensibility.VSSdkCompatibility.AsyncServiceProviderInjection`2.<GetServiceAsync>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.VisualStudio.Extensibility.VSSdkCompatibility.AsyncServiceProviderInjection`2.<GetServiceAsync>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at LMS.Formatter.CommandLMS.<CmdInvokeFirstCommandA>d__78.MoveNext()
Please let me know if there's any other info you need.
= = = = = Please note that this issue is most critical to me. Since all my extension's commands (except 1 that does nothing but invoke pre-command and post-command processing) access the Solution and Project my testing can proceed no further until this is resolved. = = = = =
I updated the above code based on the updated docs @https://learn.microsoft.com/en-us/visualstudio/extensibility/visualstudio.extensibility/project/project?view=vs-2022. Note that I have re-opened Issue #339 to address problems with the updated docs.
Though not specified explicitly in the above docs, I added the following to the above example
class MyAsyncPackage<IProjectSystemQueryService> : AsyncPackage
{
}
because the above docs specify "an instance of AsyncPackage
" but that is an abstract class and cannot be instantiated.
I also changed the following in the above example
IProjectSystemQueryService queryService = await CmdAsyncPackageService.GetServiceAsync();
to
MyAsyncPackage<IProjectSystemQueryService> package = new();
IProjectSystemQueryService queryService = await package.GetServiceAsync<IProjectSystemQueryService, IProjectSystemQueryService>();
when the second statement is executed the following exception is thrown
Microsoft.VisualStudio.Shell.ServiceUnavailableException: The IProjectSystemQueryService service is unavailable.
at Microsoft.VisualStudio.Shell.ServiceExtensions.<GetServiceAsync>d__3`2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at LMS.Formatter.CommandLMS.<<CmdInvokeA>g__initializeExtension|73_0>d.MoveNext()
It would be useful if someone could supply a reference or to running code or a code-snippet showing an in-proc Extension populating ProjectQueryableSpace
. The only in-proc in the Samples does not use ProjectQueryableSpace
.
Hi, we are going to update the documentation you linked to clarify the sample and suggest using AsyncServiceProviderInjection as you were doing.
For your code, if you change it to things should start working. The first argument is the service type indicator and second argument is the actual interface you query. In this case both happens to be same.
public DependencyInjectionCommand(AsyncServiceProviderInjection<EnvDTE.DTE, EnvDTE80.DTE2> wDte,
AsyncServiceProviderInjection<IProjectSystemQueryService, IProjectSystemQueryService> wProject)
Thanks, Bertan
What I've done is the following, modifying the example for out-of-proc extensions.
// Get full-name of current Project
// (it would be useful if the new Extensibility-model had a method for doing this and getting the ActiveSolution)
//
EnvDTE.Project projectDTE = (EnvDTE.Project)activeSolutionProjects.GetValue(0);
String projectPathDTE = projectDTE.FullName;
// Get ProjectSnapshot
//
IProjectSnapshot thisProject = null;
IQueryResults<IProjectSnapshot> ips = Microsoft.VisualStudio.Extensibility.QueryProjectsAsync(project => project.Where(project => project.Path == projectPathDTE)
// appropriate .With()'s
// (it would be useful if there a .WithAll() or an overload that populated all available .With()'s without the programmer having to specify each one wanted)
, CommandLMS.CommandCancellationToken;
Int32 ipsCount = ((IEnumerable<IProjectSnapshot>)ips).Count();
if (ipsCount == 1)
{
thisProject = ((IEnumerable<IProjectSnapshot>)ips).First();
}
else
{
// handle ipsCount == 0 or > 1
}
'in proc' = = = = = SEE NEXT COMMENT FOR CLEARER EXAMPLE - ignore the rest of this one = = = = = The sample code https://learn.microsoft.com/en-us/visualstudio/extensibility/visualstudio.extensibility/project/project?view=vs-2022#project-query-space-access-in-an-in-process-extension for 'in proc' is not 100% clear to me. It specifies
not specifing what
package
s definition is.What I tried is the following:
and F11
IProjectSystemQueryService queryService = await project.GetServiceAsync();
the system does work for a few seconds and then displays the source-file in the Experimental Instance (EI) as if all is ok (The EI is ready for another command) butProjectWorkspace
is not populated and all expressions I enter in the Immediate Wndow give the messageUnable to evaluate the expression.
Note that
ProjectWorkSpace
is defined in a file common to all files in the project aspublic static ProjectQueryableSpace ProjectWorkSpace { get; set; } = default;
I'm sure I misinterpreted what to do to get the
ProjectQueryableSpace
but I don't know what.