1

This question might have been answered a million times, but I cannot seem to find the correct answer.

Im pretty new to Dependency Injection, but have tried to make some DI in my Azure Function. However, now I get the error "An object reference is required for the non-static method etc.."

I simply cant figure out a way to resolve this problem.

My Azure Function looks like this:

 public class GetEloverblik
{

    private readonly ConnectionSettings _connectionSettings;
    private readonly ELoverblikAccess _eloverblikAccess;


    public GetEloverblik(IOptions<ConnectionSettings> connectionStrings, IOptions<ELoverblikAccess> eloverblikAccess)
    {
        _connectionSettings = connectionStrings?.Value ?? throw new ArgumentNullException(nameof(connectionStrings));
        _eloverblikAccess = eloverblikAccess?.Value ?? throw new ArgumentNullException(nameof(eloverblikAccess));
    }

    [FunctionName("GetEloverblik")]

    public async Task<IActionResult> Run(
        [HttpTrigger(AuthorizationLevel.Function, "get", Route = null)] HttpRequest req, ILogger log)

    {
      try
        {
            
            string token = await ElOverblikToken.GetToken(); //MY ERROR

        }
        catch (Exception ex)
        {

            log.LogInformation(ex.Message);
        }

        return new OkObjectResult("Done");
    }
}

And the ElOverblikToken.GetToken() Im calling:

 public  class ElOverblikToken    {
   
    private readonly ELoverblikAccess _eloverblikAccess;

    public  ElOverblikToken(IOptions<ConnectionSettings> connectionStrings, IOptions<ELoverblikAccess> eloverblikAccess)
    {            
        _eloverblikAccess = eloverblikAccess?.Value ?? throw new ArgumentNullException(nameof(eloverblikAccess));
    }
    public async Task<string> GetToken()
    {
        try
        {
            //Do something
            return token;
        }
        catch (Exception ex)
        {
            return null;
            //log.LogInformation(ex.Message);
        }

       
    }
}

I have tried to make my GetToken Method static

 public static async Task<string> GetToken()

But then I recieve an error on _eloverblikAccess saying it needs an object reference.

What am I missing?

Steven
  • 166,672
  • 24
  • 332
  • 435
SqlKindaGuy
  • 3,501
  • 2
  • 12
  • 29
  • ElOverblikToken seems to come from nowhere. – scaler Jun 23 '22 at 13:11
  • @scaler Im not sure what you mean? Its a class it self. Its beeing called in my function. Im not having trouble seeing it. I think the main reason behind this error is the static vs non static classes. But if I make my readonly variables not readonly im able to make my classes static and it works. But is that the way to go? – SqlKindaGuy Jun 23 '22 at 13:13
  • What I mean you don't create an instance of ElOverblikToken and it is not passed as a parameter from outside, hence the error message. So you can choose from ... await new ElOverblikToken(connectionstrings, access).GetToken() or making GetToken() static as the compile error states. Looking at your constructor of ElOverblikToken the static route might not possible as you stated. – scaler Jun 23 '22 at 13:18
  • @scaler Allright. I understand what your saying, however, that isnt working for me either. Maybe I dont understand DI enough - It should be correct to call them for every class I need the DI right? – SqlKindaGuy Jun 23 '22 at 13:29
  • If you add a proper instance of ElOverblikToken to your DI and then resolve it from DI in Run(...) or wherever then yes. – scaler Jun 23 '22 at 13:35
  • 1
    your string token = await ElOverblikToken.GetToken(); //MY ERROR can not work, !) because it is an instance method. and you would need to get an ElOverblikToken instance here, by resolving it from DI. 2) directly using types, that are not you, is not good in DI 3) also, you should not resolve it in Run method, but in the constructor, and put it into an readonly member and into the parameter list of the constructor, so the dI will resolve it for you whenever GetEloverblik is resolved 4) if you can not resolve it in the constructor, you need to declare a dependency to a factory – Michael Schönbauer Jun 23 '22 at 13:38
  • @MichaelSchönbauer How would I do that without setting the DI parameters? OR maybe I should just remove the DI from the second class and pass paramters instead – SqlKindaGuy Jun 23 '22 at 13:40
  • @SqlKindaGuy thats exactly the point. your class does not decide over which other types to use, and need it as dependency rule of thumb: whenever you write something like `new ...` and ... is not your classe, or `.xxx`, and is not your class, then its not decoupled – Michael Schönbauer Jun 23 '22 at 13:43
  • also, to get the concept of DI , i recommend to use "pure DI"/"poor mans DI" before introducing DI Containers, so you can get a feel of the concept – Michael Schönbauer Jun 23 '22 at 13:45
  • @MichaelSchönbauer Allright thanks - I will try to simplify it a bit, because this is more than I can handle for now I think :D – SqlKindaGuy Jun 23 '22 at 13:50
  • dude, dont give up. you do make an interface `ITokenProvider` which can `GetToken()` , then you do change the constructor to `GetEloverblik(IOptions connectionStrings, IOptions eloverblikAccess, ITokenProvider tokenprovider)` , constructor sets tokenprovider to the readonly member `_tokenprovider`, then in Run you do _tokenprovider.GetToken(), and in DI you register the `ElOverblikToken` class for `ITokenProvider`. ok? dont forget to let `ElOverblikToken` actually implement the `ITokenProvider` Interface. voilá – Michael Schönbauer Jun 23 '22 at 14:04
  • @MichaelSchönbauer Thanks a lot- I will try this out! You will hear from me later I guess ;) – SqlKindaGuy Jun 23 '22 at 14:14
  • yeah. also your eloverbliktoken constructor does not check for the 2nd argument, so either remove it (when its not used) or check it ;), to prevent the composition root / object graph from escalating – Michael Schönbauer Jun 23 '22 at 14:17

0 Answers0