A .csx file inside an Azure Function can use a nuget package if it's listed in the function's project.json file. Ex:
{
"frameworks": {
"net46":{
"dependencies": {
"Microsoft.ProjectOxford.Face": "1.1.0"
}
}
}
}
But what happens with shared .csx files that are placed under the Function App's root (i.e. not in a specific function)? Is there a way to introduce a nuget package at the App Function (root) level?
I've found a workaround in uploading the nuget package's dll to a shared bin folder as explained in the Azure Functions C# developer reference:
Shared assemblies are shared across all functions within a function app. To reference a custom assembly, upload the assembly to your function app, such as in a bin folder in the function app root.
Is there a way to do this better so my code depends on the nuget package and not on a dll?
The actual package references are managed in each function (i.e. there's no function app level set of package references), but when brought into your function by using the #load directive, shared CSX files become part of the same compilation unit, and are able to consume assembly/package references defined in your function. But you still need to manage those at the function level.
You can think of the #load behavior as a linked file in a regular C# project, where the file is brought in, but compiled within the context of the project. That applies to functions here.
Related
I am struggling to find the way to have 2 Azure functions in different language(C# and node.js) in Azure functions Project vs 2017.
Is there a way to do that?
Thanks!
Update
This method is invalid for v2 function(runtime ~2) because now it's required to use single language in one function app. See announcement.
So, the 2 project doesn't replace the functions created by first project?
Do you mean that you found some functions are replaced after new project being deployed to Azure?
Normally they won't be replaced unless functions in new project has same function names as ones already deployed.
create Azure Functions in 2 different language(C#, node.js) under one VS project
#Mikhail is right, VS doesn't provide ways for using js Azure function. No template and debug support for now.
But if you just want to run and deploy them together using VS, with no need to debug nodejs function, there's a workaround.
Generally speaking, you have to manually add nodejs function folder structure to VS project as below.
A folder named after your js function includes function.json and xxx.js file. If you have some packages installed by npm, also add package.json and node_modules folder.
function.json, xxx.js and package.json should be set as Copy if newer, so that they can be included in output dir like c# complied dll.
Not need to include node_modules locally, function host will locate them automatically. While after deploying to azure, you need to visit kudu(https://{functionappname}.scm.azurewebsites.net/DebugConsole). Execute npm install in console under wwwroot folder to install packages in package.json.
And some function templates if needed.
So I have some Azure Functions I need to publish, which I want to do via a functions project. However, those functions rely on references to class libraries within my solution, and the references do not work within a functions project, is there a way around this?
Edit: After adding the references to the other projects, when "using" the namespaces in which the classes are kept, the compiler throws an error "cannot resolve symbol", it is as if the reference does not exist. The functions project will not build because it cannot find the namespace in which the classes exist
Verify that each project targets the same version of .NET framework. I had the same problem until I noticed that the referenced project targeted 4.7.1, but my Azure function project targeted 4.6.1. Changing the referenced project to match the Azure function project resolved the issue.
There are a couple more steps to consume assemblies if they're not exposed by default in Azure Functions. If it's a custom assembly you have to make sure it's included in the bin folder. Then you have to make sure you're using the #r directive. Are you doing both of those things? Include your code header and settings if so.
This page has the list of assemblies that are visible to Azure Functions, some still requiring the #r directive:
https://learn.microsoft.com/en-us/azure/azure-functions/functions-reference-csharp#referencing-external-assemblies
The following assemblies are automatically added by the Azure Functions hosting environment:
mscorlib
System
System.Core
System.Xml
System.Net.Http
Microsoft.Azure.WebJobs
Microsoft.Azure.WebJobs.Host
Microsoft.Azure.WebJobs.Extensions
System.Web.Http
System.Net.Http.Formatting
The following assemblies may be referenced by simple-name (for
example, #r "AssemblyName"): Newtonsoft.Json
Microsoft.WindowsAzure.Storage Microsoft.ServiceBus
Microsoft.AspNet.WebHooks.Receivers Microsoft.AspNet.WebHooks.Common
Microsoft.Azure.NotificationHubs
We have an Azure function which references an external assembly via a private Nuget feed.
The problem we're having is that we have two different versions of Microsoft.Azure.WebJobs.dll - one which is a dependency of our nuget package and another which I'm assuming is being provided by the runtime.
error CS1503: Argument 2: cannot convert from 'Microsoft.Azure.WebJobs.ICollector<Microsoft.WindowsAzure.Storage.Table.ITableEntity> [D:\Program Files (x86)\SiteExtensions\Functions\1.0.10635\bin\Microsoft.Azure.WebJobs.dll]' to 'Microsoft.Azure.WebJobs.ICollector<Microsoft.WindowsAzure.Storage.Table.ITableEntity>
I found this question which says that binding redirects are not supported:
Azure Functions binding redirect
We could try to remove our dependency on that library, or we could match the version used by Azure Functions, but I think we're going to have the same problem with using Microsoft.WindowsAzure.Storage anyway.
Please advise!
You are correct that binding redirects are not supported. The runtime has its own dependencies on the WebJobs SDK and Storage libraries so objects passed into your functions will be from those versions. I recommend removing your dependencies on other versions and snapping to ours. Note that for these libraries, you don't have to add your own package reference, you can reference ours in your function code via:
#r "WindowsAzure.Storage"
You don't need to add explicit #r references for WebJobs SDK types (e.g. ICollector<T>) - the runtime adds that assembly implicitly. Of course this only applies for function code we're compiling for you, not code coming from your external packages.
In the future we might improve things in this area, but for now you'll be swimming up stream if you try to use conflicting versions.
I am facing strange issues with privates assemblies in azure functions, I have an Azure Function App with five functions which have a shared bin folder where I place my assemblies, these assemblies in turn depend on Entity Framework and LinqKit for which I have added dependencies in all the project.json files for each function but private assemblies are unable to get reference to these and failing. Please help.
Project.json --
{
"frameworks": {
"net46":{
"dependencies": {
"EntityFramework": "6.1.3",
"Newtonsoft.Json": "9.0.1",
"LinqKit": "1.1.7.2"
}
}
}
}
To clarify further in my Function App I have five different functions which depend on 2 private assemblies and I do not want to keep separate copies (as this might cause different versions of the same dll in different folder causing issues) in each function so I have created a shared bin folder from where the private assemblies are referenced but the issue happens as these private assemblies further depend on some nuget packages which they are not able to find them --
#r "..\bin\Marketware.Domain.dll"
#r "..\bin\Marketware.AzureIntegration.dll"
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Diagnostics.Eventing.Reader;
If you want to use your private assembly (not from nuget) you have to do this:
Connect to Functions App ftp
Create bin folder in folder with your function (where is run.csx)
Upload your custom assembly to newly created bin folder
Update function code and add reference
Unfortunately this dll needs to be in each function folder where needed.
Example
#r "CustomAssembly.dll"
using System.Net;
using CustomAssembly;
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
CustomAssemblyClass.MethodName(); // here call your method
return req.CreateResponse(HttpStatusCode.OK, "");
}
Will spend a bit of time trying to repro your scenario as, at a first glance, it should work as expected. In the meantime, a couple of options you have are:
1- When deploying your shared assemblies, copy all the binaries from your project output, including their dependencies. The shared assemblies folder will be in the probing logic and they would be resolved from there. This would also eliminate the need to have a project.json referencing the dependencies on each function.
2- Create a NuGet package for your shared assemblies and, on that package, specify your package dependencies (EF and LinqKit), publish that package to a private feed (which could be something like MyGet or even a folder in your function app). Your functions would only need to reference that package and not its dependencies, as those would be automatically resolved. You can find more information about using custom sources here: How do you use custom NuGet feeds with Azure Functions?
Although it may require a bit more work at first, both options have advantages over your original approach (including eliminating the need for the functions to be aware of indirect dependencies) and should be more reliable.
Hope this helps!
For my Worker role I run a custom task to modify the dll. However, when I use VS to publish the project to Azure the original binary is deployed and not the modified dll. Why is this happening? How to include the modified binary in the package from within VS
This is with sdk+tools v1.6
A possible workaround that I see, is to extract all the code/logic that requires assmebly modification in a separate class library project. Do the custom post-build modification on the class library.
In your worker add reference to that class library. If it also does not work when you add the reference as a project reference, then just copy the resulted modified assembly in a common external references folder for the solution, and add the reference from there (just browse to the final assembly).
I don't know the nature of your modification, but I think that if you cave all your "private" code in a separate class library it will be enough. As the worker implementation will just be calling a "Run()" or similar method of your class library, inside the Run() method of the RoleEntryPoint.