简体   繁体   中英

Dependency Injection C#

I am getting this error when I Debug : "InvalidOperationException: Unable to resolve service for type 'AppOwnsData.Services.PowerBiServiceApi' while attempting to activate 'AppOwnsData.Controllers.HomeController'. "

I have tried rewriting both the code in the Controller and Startup but still throwing the same error. Will appreciate help on this. Thanks!

StartUp.cs:

public void ConfigureServices(IServiceCollection services) {

services.AddMicrosoftIdentityWebAppAuthentication(Configuration)
        .EnableTokenAcquisitionToCallDownstreamApi()
        .AddInMemoryTokenCaches();

        services.AddScoped(typeof(PowerBiServiceApi));

        services.AddControllersWithViews(options => {
            var policy = new AuthorizationPolicyBuilder()
                .RequireAuthenticatedUser()
                .Build();
            options.Filters.Add(new AuthorizeFilter(policy));
        });
        services.AddRazorPages()
                .AddMicrosoftIdentityUI();
    }

HomeController.cs:

public class HomeController : Controller
    {
    private PowerBiServiceApi powerBiServiceApi;

    public HomeController(PowerBiServiceApi powerBiServiceApi)
    {
        this.powerBiServiceApi = powerBiServiceApi;
    }

PowerBiServiceApi.cs:

public class PowerBiServiceApi  {

    private ITokenAcquisition tokenAcquisition { get; }
    private string urlPowerBiServiceApiRoot { get; }

    public PowerBiServiceApi(IConfiguration configuration, ITokenAcquisition tokenAcquisition) {
        this.urlPowerBiServiceApiRoot = configuration["PowerBi:ServiceRootUrl"];
        this.tokenAcquisition = tokenAcquisition;
    }

You need to configure PowerBiServiceApi to dependency injection before using it in your controller. Now your PowerBiServiceApi needs urlPowerBiServiceApiRoot which for the sake of reusable code should be made a config. You should abstract this string to an config class such as

    /// <summary>
    /// PowerBiOptions
    /// </summary>
    public class PowerBiOptions
    {
        /// <summary>
        /// Url to the powerbi service api
        /// </summary>
        public string UrlPowerBiServiceApiRoot { get; set; }
    }

This can then be configured in dependency injection as

 services.Configure<PowerBiOptions>(x =>
        {
            x.UrlPowerBiServiceApiRoot = Configuration["PowerBi:UrlPowerBiServiceApiRoot"];
        });

This can then be used in your PowerBiServiceApi constructor as

     public class PowerBiServiceApi
    {

        private readonly PowerBiOptions PowerBiOptions;
        private ITokenAcquisition tokenAcquisition { get; }

        public PowerBiServiceApi(IOptions<PowerBiOptions> PowerBiOptionsAccessor, ITokenAcquisition tokenAcquisition)
        {
            this.PowerBiOptions = PowerBiOptionsAccessor?.Value;
            this.tokenAcquisition = tokenAcquisition;
        }
    }

You can then pass more than one config for your PowerBiServiceApi without having it on your class constructor.

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