简体   繁体   中英

How to run non-static code that uses dependency injection in .net core

I created a new console app in VS2017 and I am trying to run this code to demonstrate I can encrypt and decrypt strings in .NET Core. I have tried calling RunSample from the Program.cs Main but it wants it to be a static method. If I make RunSample static then I'm getting a null reference exception when trying to set the 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}");
    }
}

How can I run it?

UPDATE: Trying to run it from Program.cs, I have the following but .MyClass has a "cannot resolve" syntax error / red underline on it.

using System;

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

UPDATE 2:

I created my app by going to new project, .NET Core and then Console App (.NET Core): 在此处输入图片说明

UPDATE 3: I've changed my code as suggested but have the following error: 在此处输入图片说明

UPDATE 4: I've removed the using as suggested, but now I get: 在此处输入图片说明

you need DI your IDataProtector in Program.cs

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();
        }
    }
}

update - 1:

Install from NuGet

Install-Package Microsoft.Extensions.DependencyInjection

update - 2:

remove using like this

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

update - 3:

My code is DI example... you need change like this

ServiceCollection services = new ServiceCollection();

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

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

Install from NuGet

Install-Package Microsoft.AspNetCore.DataProtection

The complaint about making RunSamples static is because you're not newing up the class that defines it. If it's not an instance, then the method must be static to access it. However, since the class (and method) has a dependency that needs to be satisfied, you cannot make it static. Simply, you need to use dependency injection to create an instance of your class with its dependency satisfied in order to call the RunSamples method.

To use dependency injection in a console app, it's as simple as adding the Microsoft.Extensions.DependencyInjection NuGet package, and then:

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

However, that's not very useful as you haven't registered anything, so just do all that before calling BuildServiceProvider :

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

Since you want to utilize data protection, you'll obviously need the Microsoft.AspNetCore.DataProtection NuGet as well.

Then, when you want an instance of MyClass :

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

I guess this is what you are missing (from this link: 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();
}

You have to initiate an instance of IDataProtectionProvider by calling ActivatorUtilities.CreateInstance

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM