Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在不调用.Result的情况下使用作为任务注入的类中的函数?_C#_.net_Multithreading_Dependency Injection_Blazor - Fatal编程技术网

C# 如何在不调用.Result的情况下使用作为任务注入的类中的函数?

C# 如何在不调用.Result的情况下使用作为任务注入的类中的函数?,c#,.net,multithreading,dependency-injection,blazor,C#,.net,Multithreading,Dependency Injection,Blazor,我试图在这里实现lolsharp给出的答案: 它们注入GrpcChannel类型的任务,其中GrpcChannel是一个类: @inject Task<GrpcChannel> Channel 为了避免在频道上调用.Result,您必须等待它。例如: var通道=等待通道; GetAllResponse GetAllResponse= wait channel.GetAllAsync(新的Google.Protobuf.WellKnownTypes.Empty()); 旁注:正如

我试图在这里实现lolsharp给出的答案:

它们注入GrpcChannel类型的任务,其中GrpcChannel是一个类:

@inject Task<GrpcChannel> Channel

为了避免在
频道上调用
.Result
,您必须等待它。例如:

var通道=等待通道;
GetAllResponse GetAllResponse=
wait channel.GetAllAsync(新的Google.Protobuf.WellKnownTypes.Empty());
旁注:正如我在评论中提到的,您通常应该避免在对象解析期间执行任何涉及I/O的操作,因为这会使对象解析变得脆弱和不稳定。相反,您应该能够像Mark Seemann所表示的那样,以con-confidence的方式构建对象图。您可以通过将任务隐藏在抽象后面来推迟任务的创建来实现这一点。例如:

公共接口IGrpcChannelProvider
{
任务通道{get;}
}
这允许您将所有注册代码移动到
IGrpcChannelProvider
的实现中:

公共密封类GrpcChannelProvider:IGrpcChannelProvider,IDisposable
{
私有只读IConfiguration配置;
专用只读IAccessTokenProvider authenticationService;
专用只读惰性通道;
公共服务提供商(
IConfiguration配置,IAccessTokenProvider authenticationService)
{
this.config=config;
this.authenticationService=authenticationService;
this.channel=new Lazy(this.CreateChannel);
}
公共任务通道=>this.Channel.Value;
公共空间处置()
{
如果(this.channel.IsValueCreated)this.channel.Value.Dispose();
}
//这是您的原始代码
专用异步任务CreateChannel()
{
#如果调试
var baseUri=”http://localhost:8999/";
#否则
var baseUri=“[mysite]”;
#恩迪夫
var httpClient=新的httpClient(新的GrpcWebHandler(GrpcWebMode.GrpcWeb,新的HttpClientHandler());
var tokenResult=wait this.authenticationService.RequestAccessToken();
if(tokenResult.TryGetToken(out-var-token))
{
var credentials=CallCredentials.FromInterceptor((上下文、元数据)=>
{
如果(!string.IsNullOrEmpty(token.Value))
{
Add(“Authorization”、$“Bearer{token.Value}”);
}
返回Task.CompletedTask;
});
var channel=GrpcChannel.ForAddress(baseUri,
新的GRPCC选项
{
HttpClient=HttpClient,
Credentials=ChannelCredentials.Create(新建SslCredentials(),凭据)
});
var客户端=新的GrpcServices.GrpcServicesClient(通道);
返回客户;
}
}
}
此组件可以按如下方式注册:

services.AddSingleton();
或者-如果在应用程序域期间缓存通道会导致安全问题-将组件注册为作用域:

services.addScope();
在视图中,插入此
IGrpcChannelProvider
,而不是通道:

@注入IGrpcChannelProvider提供程序
并按如下方式使用:

var channel=wait Provider.channel;
GetAllResponse GetAllResponse=
wait channel.GetAllAsync(新的Google.Protobuf.WellKnownTypes.Empty());
更进一步说,您甚至可能希望阻止对Razor页面内的服务进行任何调用,而是依赖预填充的模型:

@模型AllResponseModel

@model AllResponseModel
GetAllResponse GetAllResponse=Model.AllResponses;

现在您可以将
IGrpcChannelProvider
注入Razor
AllResponseModel

这是否回答了您的问题?你能在你正在使用的startup.cs中发布你的依赖关系吗?@hotel不,这就是我的问题所在。第二个答案在解释如何使用该类之前就停止了。@Dan我已经从Program.cs添加了依赖项。请防止在对象解析期间执行任何涉及I/O的操作。这使得决议变得脆弱和不稳定。相反,你应该能够。谢谢。实际上,我一直在努力实现您之前发布的文章中的建议,但这些具体说明肯定会使这项任务更容易。
builder.Services.AddSingleton(async services =>
        {
            Console.WriteLine("In addsingleton");
            var config = services.GetRequiredService<IConfiguration>();
            #if DEBUG
            var baseUri = "http://localhost:8999/";
#else
            var baseUri = "[mysite]";
#endif
            Console.WriteLine("About to set new httpclient");
            var httpClient = new HttpClient(new 
GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler()));
            
            var scopedFactory = 
services.GetRequiredService<IServiceScopeFactory>();
            using (var scope = scopedFactory.CreateScope())
            {
                
                var authenticationService = 
scope.ServiceProvider.GetRequiredService<IAccessTokenProvider>();

                var tokenResult = await 
authenticationService.RequestAccessToken();
                
                if (tokenResult.TryGetToken(out var token))
                {
                    var credentials = CallCredentials.FromInterceptor((context, metadata) =>
                    {
                        if (!string.IsNullOrEmpty(token.Value))
                        {
                            metadata.Add("Authorization", $"Bearer 
{token.Value}");
                        }
                        return Task.CompletedTask;
                    });

                    var channel = GrpcChannel.ForAddress(baseUri, new 
GrpcChannelOptions { HttpClient = httpClient, Credentials = 
ChannelCredentials.Create(new SslCredentials(), credentials) });
                    var client = new 
GrpcServices.GrpcServicesClient(channel);
                    return client;
                }
            }