Developing Azure Function with Visual Studio [Update]

Azure Function is a service that separates Azure Web Job, one of the functions included in Azure App Service, into separate products. Unfortunately, the rich IDE support in Visual Studio is not yet available. In addition, the method published in Microsoft Docs is also referred to as using the Azure Function setting indirectly or utilizing the CLI for Node.

My intention is to use Visual Studio’s console project and the Azure Storage Emulator. It is about developing and testing C# Azure Function as a normal C# Compiler-based project, not C# Script, and migrating it to C# Azure Function. If you are purchasing and using the LINQPAD Premium Version, you can do the same in LINQPAD, so you will be able to develop Azure Function more actively.

Getting Started

Because Azure Function is based on Azure Web Job, there is some compatibility between Azure Function and Web Job SDK which was originally released for .NET. In other words, rather than writing something new with C# scripts, it’s more like the nature of an Azure function that you packaged your existing SDK for use in C# scripts. Unfortunately, it’s not exactly the same code base, but there is an advantage to be able to do because of compatibility, and that’s part of it.

To begin, check that the following software stack is installed:

  • Azure Storage Emulator (included in the Azure Cloud Service SDK)
  • Visual Studio 2015 or later
  • .NET Framework 4.6 or later

If your environment is not Windows development environment, Azure Storage Emulator is not provided. In this case, you will inevitably have to create and connect the actual Azure Storage account. For the IDE, you can use Visual Studio Code, Visual Studio for Mac, or Rider instead. And you can install Mono to proceed with development. Unfortunately, .NET Core is not supported as of April 2017.

Create a console project with your preferred IDE, then install the following NuGet packages:

  • Microsoft.Azure.WebJobs (2.0.0+)
  • Microsoft.Azure.WebJobs.Extensions (2.0.0+)

Then code the Main method as follows:

var jobHostConfig = new JobHostConfiguration("UseDevelopmentStorage=true");
jobHostConfig.UseCore();
jobHostConfig.UseFiles();
jobHostConfig.UseTimers();
jobHostConfig.UseDevelopmentSettings();

using (var cts = new CancellationTokenSource())
using (var jobHost = new JobHost(jobHostConfig))
{
    jobHost.StartAsync(cts.Token);
    Console.WriteLine("Press Ctrl + C to stop the service.");
    Console.CancelKeyPress += (s, e) => cts.Cancel();
    cts.Token.WaitHandle.WaitOne(Timeout.Infinite);
}

In Windows environment that can use the Local Azure Storage Emulator, specify the “UseDevelopmentStorage=true” connection string. In other environments, the connection string of the actual Azure Storage Account must be found and assigned on the property blade.

Then code the function you want to host in the Azure function as follows:

public static void Run(
    [TimerTrigger("* * * * * *", UseMonitor = true)]
    TimerInfo myTimer,
    TraceWriter log)
{
    log.Info($"C# Timer trigger function executed at: {DateTime.Now}");
}

Note that the TimerTrigger is specified in the TimerInfo method argument. The first argument to TimerTrigger indicates the interval at which the timer runs. It is recommended that you learn the grammar because it is convenient to migrate to Azure Function by configuring to specify the value by referring to the repeat interval display syntax used in Crontab.

To check if it is running well, start the Azure Storage Emulator and press F5 to run the sample program. If the output is similar to the following, it is normal.

Press Ctrl + C to stop the service.
Development settings applied
Found the following functions:
TimerSample.Run
Singleton lock acquired (1ce1ebaf1e584866b90488a9e1b5d19f/TimerSample.Run.Listener)
The next 5 occurrences of the schedule will be:
2017-04-24 오전 12:16:59
2017-04-24 오전 12:17:00
2017-04-24 오전 12:17:01
2017-04-24 오전 12:17:02
2017-04-24 오전 12:17:03
Job host started
Executing 'TimerSample.Run' (Reason='Timer fired at 2017-04-24T00:16:59.0273081+09:00', Id=aa02dc0a-5a89-4ebd-bf08-8182cce53a0c)
C# Timer trigger function executed at: 2017-04-24 오전 12:16:59
Executed 'TimerSample.Run' (Succeeded, Id=aa02dc0a-5a89-4ebd-bf08-8182cce53a0c)
Executing 'TimerSample.Run' (Reason='Timer fired at 2017-04-24T00:17:00.0061625+09:00', Id=f8161e5d-c989-4d2d-9a49-cb5d9d269134)
C# Timer trigger function executed at: 2017-04-24 오전 12:17:00
Executed 'TimerSample.Run' (Succeeded, Id=f8161e5d-c989-4d2d-9a49-cb5d9d269134)

Migration

There is one useful service that you can use to check if this Azure function is really doing well. Try Azure App Service allows you to sign in with a Google (GMAIL), Facebook, or Github account in addition to your Microsoft account to get a one-hour test Azure Function account, regardless of your actual Microsoft Azure subscription.

Visit https://azure.microsoft.com/en-us/try/app-service/ to create a new account.

Next, copy the code for the Run method above. However, there are some parts to be corrected or confirmed before some copying.

  • You must specify a reference to the NuGet package referenced during development. The project.json file is not created by default, so you need to create the following skeleton and copy the contents of the package.config file in the project you are currently developing into. Except for the packages that are automatically installed depending on the dependency, you can specify only those packages that you actually added.
{
  "frameworks": {
    "net46":{
      "dependencies": {
        "Microsoft.ProjectOxford.Face": "1.1.0"
      }
    }
   }
}
  •  If you refer to an assembly or individual .NET DLL file in the BCL rather than in the NuGet package, use the #r directive, which is unique to C # scripts, to specify a reference.
    • The .NET DLL files installed in the GAC or separately referenced manually must be uploaded directly to the bin folder.
    • It can not be used if it is a DLL that is explicitly built for x86, or when it requires operations such as system registry changes during preparation and use.
  • Before you move the function, check that the method name and signature are the same as when you first created the Azure function. If it does not run normally, refer to the function.json file.
{
  "disabled": false,
  "bindings": [
    {
      "name": "myTimer",
      "type": "timerTrigger",
      "direction": "in",
      "schedule": "0 */5 * * * *"
    }
  ]
}
  • Lastly, check the value of the argument specified in the trigger, such as TimerTrigger, BlobTrigger, or ServiceBusTrigger, and modify the function.json file. In the example above, we set it to run every second, so we need to change the schedule property of function.json to “* * * * * *”.

Wrapping-up

You can freely distribute the final version of the CSX file created as a result with the actual Azure Function service. For continuous development, it might be more convenient to set it up to distribute through the version control repository.

Here are some of the things that I think I might have a little more worrying about as I write this article:

  • HTTP Trigger, and Web Hook Trigger have no direct relationship with Web Jobs, and are close to a subset of the ASP.NET Web API. Only the parts that use the TraceWriter class are completely related to Web Job. In this regard, it seems that you can create a DummyTraceWriter class to do unit testing.
class DummyTraceWriter : TraceWriter
{
    public DummyTraceWriter() : base(default(TraceLevel)) { }
    public override void Trace(TraceEvent traceEvent) => Console.WriteLine(traceEvent);
}
  • If you create and share a script template for LINQPAD, I think you will be able to develop and test more Azure functions before the full SDK is released.
  • The NuGet package, which contains some native code, probably expects that using packages built for 64-bit will not be a problem for execution. If the 32-bit version of the package is also run as a separate EXE file, the Windows-on-Windows compatibility feature will ensure execution.

Supplement to HTTP Triggers

HTTP Trigger is a unique function that exists only in Function. It differs from existing Web Job based development method. It is provided as an output function that waits for HTTP requests and returns an HTTP response. Unfortunately, the Azure function only supports output for HTTP responses, and as of May 2017, it does not support output that invokes Web Invocation from somewhere else.

The method I introduced in this article is about local development of triggers that indirectly call a function in conjunction with several Azure components.

If you need to develop based on HTTP triggers that can be called directly, rather than in the form of Web Jobs, refer to Justin Yoo’s article and develop Azure Function App as an ASP.NET Web Project and publish it to Function App It is recommended to choose.

For more information, please visit http://blog.aliencube.org/en/2017/04/30/precompiled-azure-functions-revisited/.
It would be very helpful if you could give me some more details, a part to supplement, or a part to fix.

글쓴이: 남정현

http://www.rkttu.com

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Google+ photo

Google+의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

%s에 연결하는 중

This site uses Akismet to reduce spam. Learn how your comment data is processed.