【问题标题】:How to run non-static code that uses dependency injection in .net core如何在 .net 核心中运行使用依赖注入的非静态代码
【发布时间】:2018-07-10 16:46:59
【问题描述】:

我在 VS2017 中创建了一个新的控制台应用程序,并尝试运行此代码以证明我可以在 .NET Core 中加密和解密字符串。我曾尝试从 Program.cs Main 调用 RunSample,但它希望它是一个静态方法。如果我将 RunSample 设为静态,那么在尝试设置 var protectedpayload 时会出现空引用异常。

using System;
using Microsoft.AspNetCore.DataProtection;

public class MyClass
{
    private readonly IDataProtector _protector;

    public MyClass(IDataProtectionProvider provider)
    {
        _protector = provider.CreateProtector("Contoso.MyClass.v1");
    }

    public void RunSample()
    {
        Console.WriteLine("Enter input:");
        string input = Console.ReadLine();

        var protectedPayLoad = _protector.Protect(input);
        Console.WriteLine($"Protect returned: {protectedPayLoad}");

        var unprotectedPayLoad = _protector.Unprotect(protectedPayLoad);
        Console.WriteLine($"Unprotect returned: {unprotectedPayLoad}");
    }
}

如何运行它?

更新: 尝试从 Program.cs 运行它,我有以下内容,但 .MyClass 有一个“无法解析”语法错误/红色下划线。

using System;

namespace encrypttest
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            new Program().MyClass.RunSample();
        }
    }
}

更新 2:

我通过转到新项目、.NET Core 和控制台应用程序 (.NET Core) 创建了我的应用程序:

更新 3: 我已按照建议更改了代码,但出现以下错误:

更新 4: 我已经按照建议删除了使用,但现在我得到了:

【问题讨论】:

  • 你需要一个类的实例来运行它。向我们展示你是如何从 main 方法调用它的
  • 这里的依赖注入在哪里?我怀疑你根本没有创建(或注入)这个类。
  • @DavidG 我该怎么做?我需要一个 startup.cs 吗?
  • @maccettura 我已经添加了 Program.cs 代码
  • 好吧,你这里根本没有依赖注入,为什么你认为你有?

标签: c# .net visual-studio asp.net-core console-application


【解决方案1】:

你需要在 Program.cs 中 DI 你的 IDataProtector

class Program
{
    static void Main(string[] args)
    {
        ServiceCollection services = new ServiceCollection();

        services.AddScoped<IDataProtector>();
        services.AddScoped<MyClass>();

        using (var serviceProvider = services.BuildServiceProvider())
        {
            var service = serviceProvider.GetService<MyClass>();
            service.RunSample();
        }
    }
}

更新 - 1:

从 NuGet 安装

Install-Package Microsoft.Extensions.DependencyInjection

更新 - 2:

像这样删除使用

var serviceProvider = services.BuildServiceProvider()
var service = serviceProvider.GetService<MyClass>();
service.RunSample();

更新 - 3:

我的代码是 DI 示例... 你需要这样的改变

ServiceCollection services = new ServiceCollection();

services.AddDataProtection();
services.AddScoped<MyClass>();

var serviceProvider = services.BuildServiceProvider();
var service = serviceProvider.GetService<MyClass>();
service.RunSample();

从 NuGet 安装

Install-Package Microsoft.AspNetCore.DataProtection

【讨论】:

  • 我缺少一个用于 ServiceCollection 的方法?
  • 安装包 Microsoft.Extensions.DependencyInjection
  • 我已经用现在给我的错误更新了我的问题。查看最终图像
  • 去掉使用,因为你的MyClass没有继承IDisposable
  • 好的,我还有一个问题 - 请参阅问题更新。
【解决方案2】:

关于将RunSamples 设为静态的抱怨是因为您没有更新定义它的类。如果它不是一个实例,那么该方法必须是静态的才能访问它。但是,由于类(和方法)具有需要满足的依赖关系,因此您不能将其设为静态。简单地说,您需要使用依赖注入来创建一个满足其依赖关系的类的实例,以便调用RunSamples 方法。

要在控制台应用中使用依赖注入,只需添加Microsoft.Extensions.DependencyInjection NuGet 包,然后:

var services = new ServiceCollection()
    .BuildServiceProvider();

但是,这并不是很有用,因为您还没有注册任何东西,所以请在致电BuildServiceProvider 之前完成所有这些操作:

var serviceProvider = new ServiceCollection()
    .AddDataProtection()
    .AddScoped<MyClass>()
    .BuildServiceProvider();

由于您想利用数据保护,显然您还需要Microsoft.AspNetCore.DataProtection NuGet。

然后,当你想要MyClass 的实例时:

using (var scope = serviceProvider.CreateScope())
{
    var myClass = scope.GetRequiredService<MyClass>();
    myClass.RunSamples();
}

【讨论】:

  • 感谢您的帮助。我对 Microsoft.AspNetCore.DataProtection 的使用是灰色的,并且说代码不需要它,但是 .AddDataProtection 带有红色下划线。
  • “ServiceCollection 不包含 AddDataProtection 的定义”是错误
【解决方案3】:

我想这就是您所缺少的(来自此链接:https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/using-data-protection?view=aspnetcore-2.1

public static void Main(string[] args)
{
    // add data protection services
    var serviceCollection = new ServiceCollection();
    serviceCollection.AddDataProtection();
    var services = serviceCollection.BuildServiceProvider();

    // create an instance of MyClass using the service provider
    var instance = ActivatorUtilities.CreateInstance<MyClass>(services);
    instance.RunSample();
}

您必须通过调用 ActivatorUtilities.CreateInstance

来启动 IDataProtectionProvider 的实例

【讨论】:

  • ServiceCollection 和 ActivatorUtilities 带有红色下划线 - 我缺少什么用途?
  • 我使用 Microsoft.Extensions.DependencyInjection 添加;但现在我在.AddDataProtection 上遇到语法错误 - 服务集合不包含它的定义。
猜你喜欢
  • 1970-01-01
  • 2018-12-14
  • 1970-01-01
  • 2019-02-16
  • 1970-01-01
  • 2019-02-07
  • 2021-03-02
  • 2021-03-29
  • 2020-01-17
相关资源
最近更新 更多