Open mzj opened 4 months ago
I also encountered the same problem!
It is hoped that WithEnvironment
and WithReference
methods will be provided on sidecarBuilder
. The former provides environment variables to Sidecar, and the latter can inject the endpoint of any resource (for example, rabbitmq connection string) as an environment variable. In this way, Dapr's configuration file can associate the corresponding configuration with the environment variable. For example: var rabbitmq = builder.AddRabbitMQ("rabbitmq")
gets a rabbitmq resource. The connection string of the resource needs to be used in Dapr to configure the PubSub component. Dapr itself provides retrieval of configuration items from environment variables.For some reason, the preview version a long time ago was fine, but now the official version is not working.
The previous solution was here, but it is no longer valid.
This way, while it is possible to set environment variables for the sidecar, it is not very elegant and beautiful.
builder.AddProject<Projects.DaprServiceA>("servicea")
.WithDaprSidecar(
sidecarBuilder =>
{
sidecarBuilder
.WithOptions(new DaprSidecarOptions { AppId = "identity-api-dapr" })
.WithAnnotation("APP_API_TOKEN", ()=>"somesecrettoken");
}
)
This way, while it is possible to set environment variables for the sidecar, it is not very elegant and beautiful.
builder.AddProject<Projects.DaprServiceA>("servicea") .WithDaprSidecar( sidecarBuilder => { sidecarBuilder .WithOptions(new DaprSidecarOptions { AppId = "identity-api-dapr" }) .WithAnnotation("APP_API_TOKEN", ()=>"somesecrettoken"); } )
Thanks, bit365, but I'm getting the following error message when I try calling WithAnnotation(...) as suggested:
Cannot convert lambda expression to type 'ResourceAnnotationMutationBehavior' because it is not a delegate type
These are the only two definitions of the WithAnnotation method that I found, and neither of them takes a lambda as the second argument:
IResourceBuilder
WithAnnotation (ResourceAnnotationMutationBehavior behavior = ResourceAnnotationMutationBehavior.Append) where TAnnotation : IResourceAnnotation, new() => WithAnnotation(new TAnnotation(), behavior); IResourceBuilder
WithAnnotation (TAnnotation annotation, ResourceAnnotationMutationBehavior behavior = ResourceAnnotationMutationBehavior.Append) where TAnnotation : IResourceAnnotation;
这样,虽然可以为 sidecar 设置环境变量,但它不是很优雅和美观。
builder.AddProject<Projects.DaprServiceA>("servicea") .WithDaprSidecar( sidecarBuilder => { sidecarBuilder .WithOptions(new DaprSidecarOptions { AppId = "identity-api-dapr" }) .WithAnnotation("APP_API_TOKEN", ()=>"somesecrettoken"); } )
谢谢,bit365,但是当我尝试按照建议调用WithAnnotation(...)时,我收到以下错误消息:
无法将 lambda 表达式转换为类型“ResourceAnnotationMutationBehavior”,因为它不是委托类型
这是我找到的 WithAnnotation 方法的仅有的两个定义,它们都没有将 lambda 作为第二个参数:
IResourceBuilder WithAnnotation(ResourceAnnotationMutationBehavior behavior = ResourceAnnotationMutationBehavior.Append) where TAnnotation : IResourceAnnotation, new() => WithAnnotation(new TAnnotation(), behavior); IResourceBuilder WithAnnotation(TAnnotation annotation, ResourceAnnotationMutationBehavior behavior = ResourceAnnotationMutationBehavior.Append) where TAnnotation : IResourceAnnotation;
Sorry, I wrote it wrong. If I write it like this, it can work normally in Aspire 8.0.100. I hope it can help you.
builder.WithAnnotation(new EnvironmentCallbackAnnotation("APP_API_TOKEN", () => "somesecrettoken"))
I wrote an extension method to configure environment variables and connection strings to the Dapr sidecar. I hope it will be helpful to you. As a temporary solution, please give me some pointers. I hope the Aspire team can solve this problem as soon as possible.
public static class DaprSidecarResourceBuilderExtensions
{
private const string ConnectionStringEnvironmentName = "ConnectionStrings__";
public static IResourceBuilder<IDaprSidecarResource> WithReference(this IResourceBuilder<IDaprSidecarResource> builder, IResourceBuilder<IResourceWithConnectionString> component, string? connectionName = null, bool optional = false)
{
connectionName ??= component.Resource.Name;
builder.WithAnnotation(new EnvironmentCallbackAnnotation(context =>
{
var connectionStringName = component.Resource.ConnectionStringEnvironmentVariable ?? $"{ConnectionStringEnvironmentName}{connectionName}";
context.EnvironmentVariables[connectionStringName] = new ConnectionStringReference(component.Resource, optional);
return Task.CompletedTask;
}));
return builder;
}
public static IResourceBuilder<IDaprSidecarResource> WithEnvironment(this IResourceBuilder<IDaprSidecarResource> builder, string name, string? value)
{
return builder.WithAnnotation(new EnvironmentCallbackAnnotation(name, () => value ?? string.Empty));
}
public static IResourceBuilder<IDaprSidecarResource> WithEnvironment(this IResourceBuilder<IDaprSidecarResource> builder, string name, ReferenceExpression value)
{
return builder.WithAnnotation(new EnvironmentCallbackAnnotation(context =>
{
context.EnvironmentVariables[name] = value;
return Task.CompletedTask;
}));
}
public static IResourceBuilder<IDaprSidecarResource> WithEnvironment(this IResourceBuilder<IDaprSidecarResource> builder, string name, Func<string> callback)
{
return builder.WithAnnotation(new EnvironmentCallbackAnnotation(name, callback));
}
public static IResourceBuilder<IDaprSidecarResource> WithEnvironment(this IResourceBuilder<IDaprSidecarResource> builder, Action<EnvironmentCallbackContext> callback)
{
return builder.WithAnnotation(new EnvironmentCallbackAnnotation(callback));
}
public static IResourceBuilder<IDaprSidecarResource> WithEnvironment(this IResourceBuilder<IDaprSidecarResource> builder, Func<EnvironmentCallbackContext, Task> callback)
{
return builder.WithAnnotation(new EnvironmentCallbackAnnotation(callback));
}
public static IResourceBuilder<IDaprSidecarResource> WithEnvironment(this IResourceBuilder<IDaprSidecarResource> builder, string name, EndpointReference endpointReference)
{
return builder.WithAnnotation(new EnvironmentCallbackAnnotation(context =>
{
context.EnvironmentVariables[name] = endpointReference;
return Task.CompletedTask;
}));
}
public static IResourceBuilder<IDaprSidecarResource> WithEnvironment(this IResourceBuilder<IDaprSidecarResource> builder, string name, IResourceBuilder<ParameterResource> parameter)
{
return builder.WithAnnotation(new EnvironmentCallbackAnnotation(context =>
{
context.EnvironmentVariables[name] = parameter.Resource;
return Task.CompletedTask;
}));
}
public static IResourceBuilder<IDaprSidecarResource> WithEnvironment(this IResourceBuilder<IDaprSidecarResource> builder, string envVarName, IResourceBuilder<IResourceWithConnectionString> resource)
{
return builder.WithAnnotation(new EnvironmentCallbackAnnotation(context =>
{
context.EnvironmentVariables[envVarName] = new ConnectionStringReference(resource.Resource, optional: false);
return Task.CompletedTask;
}));
}
}
Here's how I use it
builder.AddProject<Projects.DaprServiceA>("servicea").WithDaprSidecar(options=>
{
options.WithEnvironment("testkey1","testvalue1")
.WithReference(rabbitmq);
});
这样,虽然可以为 sidecar 设置环境变量,但它不是很优雅和美观。
builder.AddProject<Projects.DaprServiceA>("servicea") .WithDaprSidecar( sidecarBuilder => { sidecarBuilder .WithOptions(new DaprSidecarOptions { AppId = "identity-api-dapr" }) .WithAnnotation("APP_API_TOKEN", ()=>"somesecrettoken"); } )
谢谢,bit365,但是当我尝试按照建议调用WithAnnotation(...)时,我收到以下错误消息:
无法将 lambda 表达式转换为类型“ResourceAnnotationMutationBehavior”,因为它不是委托类型
这是我找到的 WithAnnotation 方法的仅有的两个定义,它们都没有将 lambda 作为第二个参数:
IResourceBuilder WithAnnotation(ResourceAnnotationMutationBehavior behavior = ResourceAnnotationMutationBehavior.Append) where TAnnotation : IResourceAnnotation, new() => WithAnnotation(new TAnnotation(), behavior); IResourceBuilder WithAnnotation(TAnnotation annotation, ResourceAnnotationMutationBehavior behavior = ResourceAnnotationMutationBehavior.Append) where TAnnotation : IResourceAnnotation;
Sorry, I wrote it wrong. If I write it like this, it can work normally in Aspire 8.0.100. I hope it can help you.
builder.WithAnnotation(new EnvironmentCallbackAnnotation("APP_API_TOKEN", () => "somesecrettoken"))
This did the trick. Thank you!
builder.WithAnnotation(new EnvironmentCallbackAnnotation("APP_API_TOKEN", () => "somesecrettoken"))
I wrote an extension method to configure environment variables and connection strings to the Dapr sidecar. I hope it will be helpful to you. As a temporary solution, please give me some pointers. I hope the Aspire team can solve this problem as soon as possible.
public static class DaprSidecarResourceBuilderExtensions { private const string ConnectionStringEnvironmentName = "ConnectionStrings__";
public static IResourceBuilder<IDaprSidecarResource> WithReference(this IResourceBuilder<IDaprSidecarResource> builder, IResourceBuilder<IResourceWithConnectionString> component, string? connectionName = null, bool optional = false) { connectionName ??= component.Resource.Name; builder.WithAnnotation(new EnvironmentCallbackAnnotation(context => { var connectionStringName = component.Resource.ConnectionStringEnvironmentVariable ?? $"{ConnectionStringEnvironmentName}{connectionName}"; context.EnvironmentVariables[connectionStringName] = new ConnectionStringReference(component.Resource, optional); return Task.CompletedTask; })); return builder; } public static IResourceBuilder<IDaprSidecarResource> WithEnvironment(this IResourceBuilder<IDaprSidecarResource> builder, string name, string? value) { return builder.WithAnnotation(new EnvironmentCallbackAnnotation(name, () => value ?? string.Empty)); } public static IResourceBuilder<IDaprSidecarResource> WithEnvironment(this IResourceBuilder<IDaprSidecarResource> builder, string name, ReferenceExpression value) { return builder.WithAnnotation(new EnvironmentCallbackAnnotation(context => { context.EnvironmentVariables[name] = value; return Task.CompletedTask; })); } public static IResourceBuilder<IDaprSidecarResource> WithEnvironment(this IResourceBuilder<IDaprSidecarResource> builder, string name, Func<string> callback) { return builder.WithAnnotation(new EnvironmentCallbackAnnotation(name, callback)); } public static IResourceBuilder<IDaprSidecarResource> WithEnvironment(this IResourceBuilder<IDaprSidecarResource> builder, Action<EnvironmentCallbackContext> callback) { return builder.WithAnnotation(new EnvironmentCallbackAnnotation(callback)); } public static IResourceBuilder<IDaprSidecarResource> WithEnvironment(this IResourceBuilder<IDaprSidecarResource> builder, Func<EnvironmentCallbackContext, Task> callback) { return builder.WithAnnotation(new EnvironmentCallbackAnnotation(callback)); } public static IResourceBuilder<IDaprSidecarResource> WithEnvironment(this IResourceBuilder<IDaprSidecarResource> builder, string name, EndpointReference endpointReference) { return builder.WithAnnotation(new EnvironmentCallbackAnnotation(context => { context.EnvironmentVariables[name] = endpointReference; return Task.CompletedTask; })); } public static IResourceBuilder<IDaprSidecarResource> WithEnvironment(this IResourceBuilder<IDaprSidecarResource> builder, string name, IResourceBuilder<ParameterResource> parameter) { return builder.WithAnnotation(new EnvironmentCallbackAnnotation(context => { context.EnvironmentVariables[name] = parameter.Resource; return Task.CompletedTask; })); } public static IResourceBuilder<IDaprSidecarResource> WithEnvironment(this IResourceBuilder<IDaprSidecarResource> builder, string envVarName, IResourceBuilder<IResourceWithConnectionString> resource) { return builder.WithAnnotation(new EnvironmentCallbackAnnotation(context => { context.EnvironmentVariables[envVarName] = new ConnectionStringReference(resource.Resource, optional: false); return Task.CompletedTask; })); }
} Here's how I use it
builder.AddProject
("servicea").WithDaprSidecar(options=> { options.WithEnvironment("testkey1","testvalue1") .WithReference(rabbitmq); });
works perfectly fine, thank you for sharing!
Is there an existing issue for this?
Describe the bug
Following https://github.com/dotnet/aspire/pull/1604, when I try to call WithEnvironment(...), I'm getting the following error message:
Error (active) CS0311 The type 'Aspire.Hosting.Dapr.IDaprSidecarResource' cannot be used as type parameter 'T' in the generic type or method 'ResourceBuilderExtensions.WithEnvironment(IResourceBuilder, string, string?)'. There is no implicit reference conversion from 'Aspire.Hosting.Dapr.IDaprSidecarResource' to 'Aspire.Hosting.ApplicationModel.IResourceWithEnvironment'.
I am using .NET 8 with the following Aspire/Dapr packages:
Expected Behavior
I expected the method call to work with the final result of adding the environment variable (APP_API_TOKEN) to the Dapr sidecar.
Code in question:
Steps To Reproduce
No response
Exceptions (if any)
No response
.NET Version info
.NET SDK: Version: 8.0.302 Commit: ef14e02af8 Workload version: 8.0.300-manifests.5273bb1c MSBuild version: 17.10.4+10fbfbf2e
Anything else?
No response