Azure-docs: Show an example of how to use a service in a function

Created on 15 May 2019  Â·  13Comments  Â·  Source: MicrosoftDocs/azure-docs

This is in reference to this page: https://docs.microsoft.com/en-us/azure/azure-functions/functions-dotnet-dependency-injection

The documentation does a good job of showing how to register your services, but how do you then use these services from within a function?

For example, lets say I registered ITimestampService in startup as a singleton, and want to use it within a function. If I just declare the interface, the function run-time will not automatically pick this up. Does it need to be prefixed with an attribute?

        [FunctionName(nameof(PingContainerHttpTrigger))]
        public static IActionResult PingContainerHttpTrigger(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "ping")] HttpRequest req,
            ITimestampService timestamps)
        {
            var now = timestamps.Now();
            return new OkObjectResult(new { timestamp = now });
        }

Document Details

⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

assigned-to-author azure-functionsvc doc-enhancement triaged

Most helpful comment

After a bit of research I figured out that you no longer need to use static for function declarations so, you can use constructor inject just like you would with a Controller.

So here's the above example refactored to work:

    public class HealthFunctions
    {
        private readonly ITimestampService _timestamps;

        public HealthFunctions(ITimestampService timestamps)
        {
            _timestamps = timestamps;
        }

        [FunctionName(nameof(PingHttpTrigger))]
        public IActionResult PingHttpTrigger(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "ping")] HttpRequest req)
        {
            var now = _timestamps.Now();
            return new OkObjectResult(new { timestamp = now });
        }
    }

Either way, the documentation should explain this to the user. My 2 cents.

All 13 comments

After a bit of research I figured out that you no longer need to use static for function declarations so, you can use constructor inject just like you would with a Controller.

So here's the above example refactored to work:

    public class HealthFunctions
    {
        private readonly ITimestampService _timestamps;

        public HealthFunctions(ITimestampService timestamps)
        {
            _timestamps = timestamps;
        }

        [FunctionName(nameof(PingHttpTrigger))]
        public IActionResult PingHttpTrigger(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "ping")] HttpRequest req)
        {
            var now = _timestamps.Now();
            return new OkObjectResult(new { timestamp = now });
        }
    }

Either way, the documentation should explain this to the user. My 2 cents.

@Dave76 Thanks for the feedback! We have assigned this issue to the content author for review.

@Dave76 Hi I'm trying your sample above but apparently, I have an error during runtime

Here is my Interface declaration

namespace Microsoft.Azure.Functions.Samples.DependencyInjectionScopes.Services
{
    public class TimeStamps : ITimeStamps
    {
        public DateTime Now()
        {
            return DateTime.Now;
        }
    }
    public interface ITimeStamps
    {
        DateTime Now();
    }
}

And this is the one I implemented the DI for TimeStamps

```
public class SampleFunction
{
private readonly ITimeStamps _timeStamps;

    public SampleFunction(ITimeStamps timeStamps)
    {
        _timeStamps = timeStamps;            
    }

    [FunctionName(nameof(PingHttpTrigger))]
    public IActionResult PingHttpTrigger(
        [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "ping")] HttpRequest req, ILogger log)
    {
        log.LogInformation("Welcome call");
        var now = _timeStamps.Now();            
        return new OkObjectResult(new { timestamp = now });
    }
}

```
Here is the error :
Executed 'PingHttpTrigger' (Failed, Id=4edee1ef-c12b-4855-b5df-63076a689192)
[5/20/2019 8:05:52 AM] Microsoft.Extensions.DependencyInjection.Abstractions: Unable to resolve service for type 'Microsoft.Azure.Functions.Samples.DependencyInjectionScopes.Services.ITimeStamps' while attempting to activate 'Microsoft.Azure.Functions.Samples.DependencyInjectionScopes.SampleFunction'.

Any idea?
Thanks

Did you add the startup class and register the service?

[assembly: FunctionsStartup(typeof(Startup))]
namespace Your.Name.Space
{
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddSingleton LocalServerTimestampService>();
}
}
}

On Mon, May 20, 2019 at 2:18 AM John Christopher Eniego <
[email protected]> wrote:

@Dave76 https://github.com/Dave76 Hi I'm trying to your sample but
apparently, I have an error during runtime

Here is my Interface declaration

namespace
Microsoft.Azure.Functions.Samples.DependencyInjectionScopes.Services
{
public class TimeStamps : ITimeStamps
{
public DateTime Now()
{
return DateTime.Now;
}
}

public interface ITimeStamps
{
DateTime Now();
}

}

And this is the one I implemented the DI for TimeStamps

public class SampleFunction
{
private readonly ITimeStamps _timeStamps;

public SampleFunction(ITimeStamps timeStamps)
{
    _timeStamps = timeStamps;
}

[FunctionName(nameof(PingHttpTrigger))]
public IActionResult PingHttpTrigger(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "ping")] HttpRequest req, ILogger log)
{
    log.LogInformation("Welcome call");
    var now = _timeStamps.Now();
    return new OkObjectResult(new { timestamp = now });
}

}

Here is the error :
Executed 'PingHttpTrigger' (Failed,
Id=8dd36883-b24c-4037-b5dc-7cf876ded4a7)
[5/20/2019 6:05:57 AM]
Microsoft.Extensions.DependencyInjection.Abstractions: Unable to resolve
service for type
'Microsoft.Azure.Functions.Samples.DependencyInjectionScopes.Services.ISampleService'
while attempting to activate
'Microsoft.Azure.Functions.Samples.DependencyInjectionScopes.SampleFunction'.

Any idea ?
Thanks

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/MicrosoftDocs/azure-docs/issues/31278?email_source=notifications&email_token=AAEOS4SZD6RAETD2TLR4JYDPWI7DZA5CNFSM4HNDEK4KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODVXZPWA#issuecomment-493852632,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAEOS4V2R7JE7EYC7GXR3QLPWI7DZANCNFSM4HNDEK4A
.

Hi @Dave76
Thank you for your reply. I did add the configuration in the startup but it still doesn't work.

public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddSingleton();
}

The only thing that I can make it work is this :
I create an instance of a class instead which is not the ideal behavior when doing dependency injection

public class SampleFunction
{
private TimeStamps timeStamps = new TimeStamps();
public SampleFunction()
{
}

    [FunctionName(nameof(PingHttpTrigger))]
    public IActionResult PingHttpTrigger(
        [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "ping")] HttpRequest req, ILogger log)
    {
        log.LogInformation("Welcome call");
        var now = timeStamps.Now();            
        return new OkObjectResult(new { timestamp = now });
    }
}

Hmm. That's strange. Works fine for me. Let me see if I can post my sample
to GitHub for you so you can get the whole solution.

Dave

On Mon, May 20, 2019 at 10:51 PM John Christopher Eniego <
[email protected]> wrote:

Hi @Dave76 https://github.com/Dave76
Thank you for your reply. I did add the configuration in the startup but
it still doesn't work.

public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddSingleton();
}

The only thing that I can make it work is this :
I create an instance of a class instead which is not the ideal behavior
when doing dependency injection

public class SampleFunction
{
private TimeStamps timeStamps = new TimeStamps();
public SampleFunction()
{

[FunctionName(nameof(PingHttpTrigger))]
public IActionResult PingHttpTrigger(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "ping")] HttpRequest req, ILogger log)
{
    log.LogInformation("Welcome call");
    var now = timeStamps.Now();
    return new OkObjectResult(new { timestamp = now });
}

}

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/MicrosoftDocs/azure-docs/issues/31278?email_source=notifications&email_token=AAEOS4URR57TD76YMCPOEBDPWNPTVA5CNFSM4HNDEK4KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODV2TDII#issuecomment-494219681,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAEOS4RSHP6KJL5NWQUIPCTPWNPTVANCNFSM4HNDEK4A
.

Sure thanks :)

+ @jeffhollan who drafted this dependency injection article.

cc. @craigshoemaker

hi guys, I just had the same issue today, @oracle000 try to upgrade Microsoft.NET.Sdk.Functions to latest version 1.0.28. @ggailey777 maybe it good idea to add version which start support this behavior?

Yes this was a requirement I didn’t realize when writing the docs. In addition to installing the extension documented you do need to use a later version of function SDK. @craigshoemaker can you track this?

@rjxby sure will try it. Thank you

serverless-seminar-master.zip
Hi,

I have attached a zip of my solution which shows DI working (injecting a
service from another project).

As others have chimed in, I think your missing piece was you need to be on
the latest function sdk: 1.0.28.

Dave

On Wed, May 22, 2019 at 11:48 AM John Christopher Eniego <
[email protected]> wrote:

@rjxby https://github.com/rjxby sure will try it. Thank you

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/MicrosoftDocs/azure-docs/issues/31278?email_source=notifications&email_token=AAEOS4VO7BR5Y3GZV7JYXM3PWVTMFA5CNFSM4HNDEK4KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODV7PT3I#issuecomment-494860781,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAEOS4TIHQBYRNEQFZGOSOLPWVTMFANCNFSM4HNDEK4A
.

Hi @rjxby, @Dave76
My current version of .NET.Sdk.Function is 1.0.26 and updating it to version 1.0.28 works!
Thanks a lot for the effort guys :)

Also, thank you for including a zip file in your solution @Dave76, will check it later :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ianpowell2017 picture ianpowell2017  Â·  3Comments

mrdfuse picture mrdfuse  Â·  3Comments

Favna picture Favna  Â·  3Comments

jebeld17 picture jebeld17  Â·  3Comments

Agazoth picture Agazoth  Â·  3Comments