简体   繁体   English

在Azure函数中使用类

[英]Using classes in Azure Functions

I would like to create a class for external logging which is set up by initializing through the constructor. 我想为外部日志记录创建一个类,该类通过通过构造函数进行初始化来设置。 I then want to be able to use this class multiple times throughout the Function lifetime. 然后,我希望能够在整个功能生命周期中多次使用此类。

eg 例如

using System.Net;

private static Logger logger;

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, 
TraceWriter log, ExecutionContext executionContext)
{
    log.Info("C# HTTP trigger function processed a request.");

    string invocationId = executionContext.InvocationId.ToString();
    logger = new Logger(invocationId);

    logger.Log("Start"); 

    // parse query parameter
    string name = req.GetQueryNameValuePairs()
    .FirstOrDefault(q => string.Compare(q.Key, "name", true) == 0)
    .Value;

    // Get request body
    dynamic data = await req.Content.ReadAsAsync<object>();

    // Set name to query string or body data
    name = name ?? data?.name;

    logger.Log("Finish");

    return name == null
    ? req.CreateResponse(HttpStatusCode.BadRequest, "Please pass a name on the query string or in the request body")
    : req.CreateResponse(HttpStatusCode.OK, "Hello " + name);
}

public class Logger
{
    private string _invocationId;

    public Logger(string invocationId) 
    {
        _invocationId = invocationId;
    }

    public void Log(string message)
    {   
        message = $"{_invocationId} | {message}";
        // log to Splunk
    }
}

Is this the correct way to use my Logger class "globally" throughout the function? 这是在整个函数中“全局”使用Logger类的正确方法吗?

private static Logger logger;

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, 
TraceWriter log, ExecutionContext executionContext)
{
    log.Info("C# HTTP trigger function processed a request.");

    string invocationId = executionContext.InvocationId.ToString();
    logger = new Logger(invocationId);

Are there any implications of new'ing up classes? 上新课有什么影响吗?

This is a simplified version of what I am trying to achieve. 这是我要实现的简化版本。

Your code doesn't make much sense: you have a static field, but you assign it on every invocation. 您的代码没有多大意义:您有一个静态字段,但是您在每次调用时都对其进行了分配。 Second invocation may override the value created by the first one, so you might get unpredictable results. 第二次调用可能会覆盖第一个调用创建的值,因此您可能会得到不可预测的结果。

You should choose: either your field is static, you create it once and then use the instance on every subsequent invocation; 您应该选择:您的字段是静态的,只创建一次,然后在以后的每次调用中使用实例; or you just make a local variable and use it the way you do now. 或者您只是制作一个局部变量,然后按现在的方式使用它。

The second option is preferred unless you really need to share something across requests. 除非您确实需要在请求之间共享某些内容,否则首选第二个选项。 Avoid shared state if possible. 尽可能避免共享状态。

UPDATE: 更新:

Based on the question from your comment, here is what you could do: 根据您评论中的问题,您可以执行以下操作:

public static Task<HttpResponseMessage> Run(
    HttpRequestMessage req, ExecutionContext executionContext)
{
    string invocationId = executionContext.InvocationId.ToString();
    var processor = new Processor(invocationId);
    return processor.Process(req);
}

public class Processor
{
    private Logger logger;

    public Processor(string invocationId)
    {
        this.logger = new Logger(invocationId);
    }

    public async Task<HttpResponseMessage> Process(HttpRequestMessage req)
    {
        await this.logger.Log("Start");
        await this.DoStep1();
        await this.DoStep2();
        await this.logger.Log("Finish"); 
    }

    private async Task DoStep1()
    {
        await this.logger.Log("Step 1");
        // ...
    }

    private async Task DoStep2()
    {
        await this.logger.Log("Step 2");
        // ...
    }
}

I'm not a particular fan of this style, but if that's what you want, it will work fine. 我不是这种风格的特别拥护者,但是如果您想要的是这样,它将很好用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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