This documentation is not maintained. Please refer to doc.castsoftware.com/technologies to find the latest updates.

Extension ID

com.castsoftware.azure.dotnet

What's new?

See Azure .NET 1.0 - Release Notes.

In what situation should you install this extension?

This extension should be used for analyzing .NET source code using any of the supported Azure services. 

Azure Blob support

Click here to expand...

Whenever a call to a method carrying a CRUD operation on an Azure Blob is found in the source code, this extension evaluates the name of the container in which the operation is made and a link is created from the caller of the method to that blob container. The list of supported methods and the type of links created are listed in the following tables. If the evaluation of the container name fails (either due to missing information in the source code or to limitations in the evaluation) a link is created to an Unknown container.

For methods copying a blob from one container to another, a useSelectLink is created to the source container and both a useInsertLink and a useUpdateLink are created to the destination container.

ClassesMethodsLink types
Azure.Storage.Blobs.BlobServiceClientDeleteBlobContainer,DeleteBlobContainerAsyncuseDeleteLink
As aboveUndeleteBlobContainer, UndeleteBlobContainerAsyncuseUpdateLink

Azure.Storage.Blobs.BlobContainerClient

Delete, DeleteAsync, DeleteBlob, DeleteBlobAsync, DeleteBlobIfExists, DeleteBlobIfExistsAsync, DeleteIfExists, DeleteIfExistsAsyncuseDeleteLink

As above

GetBlobs, GetBlobsAsync

useSelectLink

Azure.Storage.Blobs.BlobContainerClient

UpoadBlob, UploadBlobAsyncuseInsertLink, useUpdateLink

Azure.Storage.Blobs.Specialized.BlobBaseClient

Azure.Storage.Blobs.Specialized.AppendBlobClient

Azure.Storage.Blobs.Specialized.PageBlobClient

Azure.Storage.Blobs.Specialized.BlockBlobClient

Azure.Storage.Blobs.BlobClient


Delete, DeleteAsync, DeleteIfExists, DeleteIfExistsAsyncuseDeleteLink

As above

DownloadContent, DownloadContentAsync, DownloadStreaming, DownloadStreamingAsync, DownloadTo, DownloadToAsync,

useSelectLink

As above

Undelete, UndeleteAsynuseUpdateLink

Azure.Storage.Blobs.BlobClient

OpenWrite, OpenWriteAsyncuseSelectLink, useUpdateLink

As above

Upload, UploadAsyncuseInsertLink, useUpdateLink

Azure.Storage.Blobs.Specialized.AppendBlobClient

AppendBlock, AppendBlockAsync, AppendBlockFromUri, AppendBlockFromUriAsyncuseUpdateLink, useSelectLink( from container in Uri)

As above

Create, CreateAsync, CreateIfNotExist, CreateIfNotExistAsyncuseInsertLink

As above

OpenWrite, OpenWriteAsyncuseSelectLink, useUpdateLink

Azure.Storage.Blobs.Specialized.PageBlobClient

ClearPages, ClearPagesAsync, useDeleteLink

As above

Create, CreateAsync, CreateIfNotExist, CreateIfNotExistAsyncuseInsertLink

As above

OpenWrite, OpenWriteAsyncuseSelectLink, useUpdateLink

As above

UploadPages UploadPagesAsync UploadPagesFromUri, UploadPagesFromUriAsync

useInsertLink, useUpdateLink, useSelectLink( from container in Uri)

Azure.Storage.Blobs.Specialized.BlockBlobClient

CommitBlockList, CommitBlockListAsyncuseUpdateLink

As above

SyncUploadFromUri, SyncUploadFromUriAsyncuseInsertLink, useUpdateLink, useSelectLink( from container in Uri)

As above

OpenWrite, OpenWriteAsyncuseSelectLink, useUpdateLink

As above

StageBlock, StageBlockAsync, StageBlockFromUri, StageBlockFromUriAsyncuseInsertLink, useSelectLink( from container in Uri)

As above

Upload, UploadAsync

useInsertLink, useUpdateLink

Example

Communicate with a single Blob Container

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Azure.Storage;
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;
using Azure.Storage.Sas;

namespace BlobAzure
{
    public class Pgm
    {
    	private readonly BlobServiceClient _blobClient;
        public async Task<bool> Delete(string file)
        {
        	_blobClient = new BlobServiceClient();
        	string containerName = "containerName";
            var containerClient = _blobClient.GetBlobContainerClient(containerName);
            await containerClient.DeleteBlobAsync(file, Azure.Storage.Blobs.Models.DeleteSnapshotsOption.IncludeSnapshots);
            return true;
        }
        
        public async Task<bool> DeleteWithContainerName(string file, string containerName)
        {
        	_blobClient = new BlobServiceClient();
            var containerClient = _blobClient.GetBlobContainerClient(containerName);
            await containerClient.DeleteBlobAsync(file, Azure.Storage.Blobs.Models.DeleteSnapshotsOption.IncludeSnapshots);
            return true;
        }
        
        public Task<bool> UploadFile()
        {
        // Get a connection string to our Azure Storage account.
			string connectionString = "<connection_string>";
			string containerName = "sample-container";
			string filePath = "hello.jpg";
			
			// Get a reference to a container named "sample-container" and then create it
			BlobContainerClient container = new BlobContainerClient(connectionString, containerName);
			container.Create();
			
			// Upload a few blobs so we have something to list
			container.UploadBlob("first", File.OpenRead(filePath));
		}
    }
}

Communicate with two Blob Containers

The following example shows a Blob containing a source Blob container which sends to the destination Blob container via an API containing a URI.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Azure.Storage;
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;
using Azure.Storage.Blobs.Specialized;
using Azure.Storage.Sas;

namespace BlobAzure
{
    public class Pgm
    {
        static string containerName = "data";
        static string filename = "sample.txt";
        static string uriCustom = "https://myaccount.blob.core.windows.net/my_source_container/myblob";
        
        static async Task GetBlobs(string connectionString, string blobName, BlobClientOptions options)
        {
            
			AppendBlobClient appendBlob = new AppendBlobClient(connectionString, containerName, blobName, options);
                        
            Uri uri = new("https://myaccount.blob.core.windows.net/my_source_container/myblob");
			var response = appendBlob.AppendBlockFromUri(uri);
        }
          
    }
}

Azure Service Bus support

Click here to expand...

Supported versions:

  • Azure.Messaging.ServiceBus
  • Microsoft.Azure.ServiceBus (deprecated version)

.NET Azure Service Bus Publisher and .NET Azure Service Bus Receiver objects are created when the following methods are used:

Object created

Methods from ServiceBusClient from Azure.Messaging.ServiceBus

Methods from ServiceBusService from Microsoft.Azure.ServiceBus (deprecated version)

.NET Azure Service Bus Publisher

SendMessageAsync

SendMessagesAsync

SendAsync

.NET Azure Service Bus Receiver

ReceiveMessageAsync,

ReceiveMessagesAsync

ProcessMessageAsync

ReceiveAsync

ReceiveDeferredMessageAsync

The name of the object created is that of the Queue (or the Topic). Whenever the evaluation of the Queue (or Topic) name fails, an Unknown object is created.

  • For publishers, a callLink  from the callable object (usually Function or Method) containing the call (to the supported method) to the publisher is added (see example below).
  • For receivers, a callLink is added from the receiver to the callable object (usually a Function or a Method) containing the call to the supported method (see example below).

Whenever an Azure Service Bus Publisher has the same name as an Azure Service Bus Receiver, the com.castsoftware.wbslinker will create a call link from the Publisher to the Receiver.

Example

Publisher creation

using Azure.Messaging.ServiceBus;
using Azure.Messaging.ServiceBus.Administration;

namespace ServiceBus
{
    public class Pgm1
    {
        private string queueName = "toto";
        
        public static async Task SendMessageAsync(string connectionString, string messageText)
        {
            await using var client = new ServiceBusClient(connectionString);
			using var messageBatch = await this.sender.CreateMessageBatchAsync();
            
            // create the sender
            ServiceBusSender sender = new ServiceBusSender(client, queueName);

            // create a message that we can send. UTF-8 encoding is used when providing a string.
            ServiceBusMessage message = new ServiceBusMessage(messageText);

            // send the message
            await sender.SendMessageAsync(message);
        }
}

Subscriber creation

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Azure.Messaging.ServiceBus;
using Azure.Messaging.ServiceBus.Administration;

namespace ServiceBus
{
    public class Pgm
    {
        private string queueName = "toto";
        
        public static async Task<ServiceBusReceivedMessage> GetMessageFromSessionAsync(string connectionString)
        {
            await using var client = new ServiceBusClient(connectionString);
                                 
            // create the sender			
			ServiceBusReceiver receiver = client.CreateReceiver(queueName);
			
            // the received message is a different type as it contains some service set properties
            return await receiver.ReceiveMessageAsync();
        }      
    }
}

Azure Event Hubs support

Click here to expand...

Whenever a call to a method carrying a sender/receiver operation on an Azure Event Hubs is found in the source code, this extension evaluates the name of the Event Hub in which the operation is made and a link is created from the caller of the method to that Event Hub Publisher/Receiver. If the evaluation of the Event Hub name fails (either due to missing information in the source code or to limitations in the evaluation) a link is created to an Unknown Event Hub Publisher/Receiver.

This extension supports:

Supported send/receive Events APIs

Azure.Messaging.EventHubs (latest)

For the publisher side (Send Events):

Supported API methods (Azure.Messaging.EventHubs.Producer)Caller typeLink createdObject created (Callee)

EventHubProducerClient.SendAsync

C# MethodcallLinkDotNet Azure Event Hub Publisher / DotNet Azure Unknown Event Hub Publisher

EventHubBufferedProducerClient.EnqueueEventAsync 

C# MethodcallLinkDotNet Azure Event Hub Publisher / DotNet Azure Unknown Event Hub Publisher
EventHubBufferedProducerClient.EnqueueEventsAsync C# MethodcallLinkDotNet Azure Event Hub Publisher / DotNet Azure Unknown Event Hub Publisher
EventHubBufferedProducerClient.FlushAsync  C# MethodcallLinkDotNet Azure Event Hub Publisher / DotNet Azure Unknown Event Hub Publisher

For the receiver side (Receive Events):

Supported API methods (Azure.Messaging.EventHubs.Consumer / Azure.Messaging.EventHubs)

Object created (Caller)Link createdCallee type

EventHubConsumerClient.ReadEventsAsync

DotNet Azure Event Hub Receiver / DotNet Azure Unknown Event Hub ReceivercallLinkC# Method

EventHubConsumerClient.ReadEventsFromPartitionAsync

DotNet Azure Event Hub Receiver / DotNet Azure Unknown Event Hub ReceivercallLinkC# Method

EventProcessorClient.StartProcessing

DotNet Azure Event Hub Receiver / DotNet Azure Unknown Event Hub ReceivercallLinkC# Method

EventProcessorClient.StartProcessingAsync

DotNet Azure Event Hub Receiver / DotNet Azure Unknown Event Hub ReceivercallLinkC# Method

Microsoft.Azure.EventHubs (legacy)

For the publisher side (Send Events):

Supported API methods (Microsoft.Azure.EventHubs)Caller typeLink createdObject created (Callee)

EventHubClient.SendAsync

C# MethodcallLinkDotNet Azure Event Hub Publisher / DotNet Azure Unknown Event Hub Publisher

PartitionSender.SendAsync

C# MethodcallLinkDotNet Azure Event Hub Publisher / DotNet Azure Unknown Event Hub Publisher

For the receiver side (Receive Events):

Supported API methods (Microsoft.Azure.EventHubs / Microsoft.Azure.EventHubs.Processor)

Object created (Caller)Link createdCallee type

PartitionReceiver.ReceiveAsync

DotNet Azure Event Hub Receiver / DotNet Azure Unknown Event Hub ReceivercallLinkC# Method

EventProcessorHost.RegisterEventProcessorAsync

DotNet Azure Event Hub Receiver / DotNet Azure Unknown Event Hub ReceivercallLinkC# Method

EventProcessorHost.RegisterEventProcessorFactoryAsync

DotNet Azure Event Hub Receiver / DotNet Azure Unknown Event Hub ReceivercallLinkC# Method

The extension com.castsoftware.wbslinker will match Azure Event Hub Publisher objects to Azure Event Hub Receiver.

Checkpoint Store

We support Azure Event Hubs Checkpoint Store using Storage Blobs for Consumer using Processor client. From C# Method which is the parent of Event Hub Receiver, we create a useUpdateLink to the blob container object. For example, when analyzing the following source code:

public class Send
{
	// connection string to the Event Hubs namespace
    private const string connectionString = "<EVENT HUBS NAMESPACE - CONNECTION STRING>";

    // name of the event hub
    private const string eventHubName = "<EVENT HUB NAME>";

    // number of events to be sent to the event hub
    private const int numOfEvents = 3;
    
    // The Event Hubs client types are safe to cache and use as a singleton for the lifetime
    // of the application, which is best practice when events are being published or read regularly.
    static EventHubProducerClient producerClient;  
    
    static async Task Send()
    {
        // Create a producer client that you can use to send events to an event hub
        producerClient = new EventHubProducerClient(connectionString, eventHubName);

        // Create a batch of events 
        using EventDataBatch eventBatch = await producerClient.CreateBatchAsync();

        for (int i = 1; i <= numOfEvents; i++)
        {
            if (! eventBatch.TryAdd(new EventData(Encoding.UTF8.GetBytes($"Event {i}"))))
            {
                // if it is too large for the batch
                throw new Exception($"Event {i} is too large for the batch and cannot be sent.");
            }
        }

        try
        {
            // Use the producer client to send the batch of events to the event hub
            await producerClient.SendAsync(eventBatch);
            Console.WriteLine($"A batch of {numOfEvents} events has been published.");
        }
        finally
        {
            await producerClient.DisposeAsync();
        }
    }
    				
}

and:

public class Receive
{
	private const string ehubNamespaceConnectionString = "<EVENT HUBS NAMESPACE - CONNECTION STRING>";
    private const string eventHubName = "<EVENT HUB NAME>";
    private const string blobStorageConnectionString = "<AZURE STORAGE CONNECTION STRING>";
    private const string blobContainerName = "<BLOB CONTAINER NAME>";
    
    static BlobContainerClient storageClient;

    // The Event Hubs client types are safe to cache and use as a singleton for the lifetime
    // of the application, which is best practice when events are being published or read regularly.        
    static EventProcessorClient processor;
    
    static async Task Receive()
    {
        // Read from the default consumer group: $Default
        string consumerGroup = EventHubConsumerClient.DefaultConsumerGroupName;

        // Create a blob container client that the event processor will use 
        storageClient = new BlobContainerClient(blobStorageConnectionString, blobContainerName);

        // Create an event processor client to process events in the event hub
        processor = new EventProcessorClient(storageClient, consumerGroup, ehubNamespaceConnectionString, eventHubName);

        // Register handlers for processing events and handling errors
        processor.ProcessEventAsync += ProcessEventHandler;
        processor.ProcessErrorAsync += ProcessErrorHandler;

        // Start the processing
        await processor.StartProcessingAsync();

        // Wait for 30 seconds for the events to be processed
        await Task.Delay(TimeSpan.FromSeconds(30));

        // Stop the processing
        await processor.StopProcessingAsync();
    }

you will get the following result:

Azure Functions support

Click here to expand...

Azure Functions allow the execution of source code in the cloud. The execution can be set to be triggered by specific Azure events. In .NET, the Azure Functions API is defined using attributes/annotations. We support two different API for Azure Function in .NET: In-process (Microsoft.Azure.WebJobs) and Out-of-process or isolated (Microsoft.Azure.Functions.Worker).

ProcessSupported API methodObject created (Caller)Link createdCallee type
#In-Process - Microsoft.Azure.WebJobsFunctionNameDotnet Azure Function or Dotnet Azure Unknown FunctioncallLinkC# Method
#Isolated - Microsoft.Azure.Functions.WorkerFunctionDotnet Azure Function or Dotnet Azure Unknown FunctioncallLinkC# Method

The analyzer will create a DotNet Azure Function object with a call link to the handler of the Azure Function. For example:

[FunctionName("WriteOneDoc")]
public static void Run(

The azure function can be configured to be triggered or to interact with some other Azure services. Triggers cause a function to run. Binding to a function is a way of declaratively connecting another resource to the function; bindings may be connected as input bindings, output bindings, or both. Data from bindings is provided to the function as parameters. The following table lists the supported interactions:

Interaction

trigger

input

output

Http(tick)--
Service Bus(tick)-(tick)
Blob(tick)(tick)(tick)
CosmosDB(tick)(tick)(tick)
Event Hubs(tick)-(tick)
SignalR Service(tick)--

Detailed support for each of these interactions is given in the following sections.

Support binding with Azure Service Bus

Service Bus Trigger

For the trigger, we create a DotNet Azure Service Bus Receiver object with a call link to the Azure Function object.

Supported API methods (#In-Process - Microsoft.Azure.WebJobs,  #Isolated - Microsoft.Azure.Functions.Worker)

Object created (Caller)

Link created

Callee type

ServiceBusTrigger

DotNet Azure Service Bus Receiver or DotNet Azure Unknown Service Bus ReceivercallLinkAzure Function

Service Bus Binding Output

For output binding, the DotNet function sends a message to a Topic or a Queue. We create a DotNet Azure Service Bus Publisher object with a callLink to that object from the handler of function.

Process

Supported API methodsObject created (Callee)Link createdCaller type
#In-Process - Microsoft.Azure.WebJobsServiceBusDotNet Azure Service Bus Publisher or DotNet Azure Unknown Service Bus PublishercallLinkC# Method
#Isolated - Microsoft.Azure.Functions.WorkerServiceBusOutputDotNet Azure Service Bus Publisher or DotNet Azure Unknown Service Bus PublishercallLinkC# Method

For example, when analyzing the following source code:

    	[Function("ServiceBusFunction")]
        [ServiceBusOutput("outputQueue", Connection = "ServiceBusConnection")]
        public static string Run([ServiceBusTrigger("queue", Connection = "ServiceBusConnection")] string item,
            FunctionContext context)
        {
            var logger = context.GetLogger("ServiceBusFunction");

            logger.LogInformation(item);

            var message = $"Output message created at {DateTime.Now}";
    	            return message;
    	}   

you will get the following result:

HttpTrigger

We create operations linked to the handler of function. If the type of operation is not specified, the function responds to all HTTP methods, we create DotNet Azure Any OperationIf the url is not specified, it is the function name.

Supported API methods (#In-Process - Microsoft.Azure.WebJobs, #Isolated - Microsoft.Azure.Functions.Worker)

Object created (Caller)

Link created

Callee type

HttpTrigger

DotNet Azure Get Operation

DotNet Azure Post Operation

DotNet Azure Put Operation

DotNet Azure Delete Operation

DotNet Azure Any Operation

callLinkAzure Function 

For example, when analyzing the following source code:

		[FunctionName("Function1")]
		public static IActionResult Run2(
		[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = "products/{category:alpha}/{id:int?}")] HttpRequest req,
		string category, int? id, ILogger log)
		{
		    log.LogInformation("C# HTTP trigger function processed a request.");

		    var message = String.Format($"Category: {category}, ID: {id}");
		    return (ActionResult)new OkObjectResult(message);
		}

you will get the following result:

Durable function

Durable Functions allow calling an azure function from another azure function.

Supported API methods (#In-Process - Microsoft.Azure.WebJobs.Extensions.DurableTask)

Object created (Callee)Link createdCaller

IDurableOrchestrationClient.StartNewAsync 

IDurableOrchestrationContext.CallSubOrchestratorAsync

IDurableOrchestrationContext.CallSubOrchestratorWithRetryAsync

IDurableOrchestrationContext.StartNewOrchestration

IDurableOrchestrationContext.CallActivityAsync 

IDurableOrchestrationContext.CallActivityWithRetryAsync

DotNet Call to Azure Function or DotNet Call to Azure Unknown FunctioncallLinkC# Method

The extension com.castsoftware.wbslinker will match DotNet Call to Azure Function objects to Azure Function objects such as DotNet Azure Function. Currently, we do not support Durable function in case of Isolated. For example, when analyzing the following source code:

		[FunctionName("Orchestrator_HttpStart")]
        public static async Task<HttpResponseMessage> HttpStart(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestMessage req,
            [DurableClient] IDurableOrchestrationClient client,
            ILogger log)
        {
            // Function input comes from the request content.
            string instanceId = await client.StartNewAsync("Orchestrator", null, "Nuget");

            log.LogInformation($"Started orchestration with ID = '{instanceId}'.");

            return client.CreateCheckStatusResponse(req, instanceId);
        }

        [FunctionName("Orchestrator")]
        public static async Task<string> RunOrchestrator(
            [OrchestrationTrigger] IDurableOrchestrationContext context)
        {
            // retrieves the organization name from the Orchestrator_HttpStart function
            var organizationName = context.GetInput<string>();
            // retrieves the list of repositories for an organization by invoking a separate Activity Function.
            var repositories = await context.CallActivityAsync<List<(long id, string name)>>("GetAllRepositoriesForOrganization", organizationName);

            // Creates an array of task to store the result of each functions
            var tasks = new Task<(long id, int openedIssues, string name)>[repositories.Count];
            for (int i = 0; i < repositories.Count; i++)
            {
                // Starting a `GetOpenedIssues` activity WITHOUT `async`
                // This will starts Activity Functions in parallel instead of sequentially.
                tasks[i] = context.CallActivityAsync<(long, int, string)>("GetOpenedIssues", (repositories[i]));
            }

            // Wait for all Activity Functions to complete execution
            await Task.WhenAll(tasks);

            // Retrieve the result of each Activity Function and return them in a list
            var openedIssues = tasks.Select(x => x.Result).ToList();

            // Send the list to an Activity Function to save them to Blob Storage.
            await context.CallActivityAsync("SaveRepositories", openedIssues);

            return context.InstanceId;
        }

		[FunctionName("GetAllRepositoriesForOrganization")]
        public static async Task<List<(long id, string name)>> GetAllRepositoriesForOrganization([ActivityTrigger] IDurableActivityContext context)
        {
            // retrieves the organization name from the Orchestrator function
            var organizationName = context.GetInput<string>();
            // invoke the API to retrieve the list of repositories of a specific organization
            var repositories = (await github.Repository.GetAllForOrg(organizationName)).Select(x => (x.Id, x.Name)).ToList();
            return repositories;
        }

        [FunctionName("GetOpenedIssues")]
        public static async Task<(long id, int openedIssues, string name)> GetOpenedIssues([ActivityTrigger] IDurableActivityContext context)
        {
            // retrieve a tuple of repositoryId and repository name from the Orchestrator function
            var parameters = context.GetInput<(long id, string name)>();

            // retrieves a list of issues from a specific repository
            var issues = (await github.Issue.GetAllForRepository(parameters.id)).ToList();

            // returns a tuple of the count of opened issues for a specific repository
            return (parameters.id, issues.Count(x => x.State == ItemState.Open), parameters.name);
        }

		[FunctionName("SaveRepositories")]
        public static async Task SaveRepositories([ActivityTrigger] IDurableActivityContext context)
        {
            // retrieves a tuple from the Orchestrator function
            var parameters = context.GetInput<List<(long id, int openedIssues, string name)>>();

            // create the client and table reference for Blob Storage
            var client = account.CreateCloudTableClient();
            var table = client.GetTableReference("Repositories");

            // create the table if it doesn't exist already.
            await table.CreateIfNotExistsAsync();

            // creates a batch of operation to be executed
            var batchOperation = new TableBatchOperation();
            foreach (var parameter in parameters)
            {
                // Creates an operation to add the repository to Table Storage
                batchOperation.Add(TableOperation.InsertOrMerge(new Repository(parameter.id)
                {
                    OpenedIssues = parameter.openedIssues,
                    RepositoryName = parameter.name
                }));
            }

            await table.ExecuteBatchAsync(batchOperation);
        }

you will get the following result:

Durable function client with HTTP trigger

It is common that a durable function client is triggered by an HTTP call and that with a proper URL any orchestrator function can be triggered. In this case, for each existing orchestrator azure function, an Operation with the corresponding url is created with a callLink to a Call to Azure Function object to the orchestrator function.

For example when analyzing the following source code:

		[FunctionName("HttpStart")]
        public static async Task<HttpResponseMessage> Run3(
            [HttpTrigger(AuthorizationLevel.Function, methods: "post", Route = "orchestrators/{functionName}")] HttpRequestMessage req,
            [DurableClient] IDurableClient starter,
            string functionName,
            ILogger log)
        {
            // Function input comes from the request content.
            object eventData = await req.Content.ReadAsAsync<object>();
            string instanceId = await starter.StartNewAsync(functionName, eventData);

            log.LogInformation($"Started orchestration with ID = '{instanceId}'.");

            return starter.CreateCheckStatusResponse(req, instanceId);
        }

if your source code contains two orchestrator azure functions named Orchestrator and Orchestrator2, you will get the following result:

Binding with Azure Blob

Blob trigger

Supported API methods (In-Process - Microsoft.Azure.WebJobs,  Isolated - Microsoft.Azure.Functions.Worker)

Link createdCaller typeCallee type

BlobTrigger 

callLinkC# MethodDotNet Azure function

Whenever a file is added or updated to a blob container the azure function will be executed. We add the property 'CAST_Azure_Function.blob_triggers' to the DotNet Azure function. The extension com.castsoftware.wbslinker will create a callLink from the method (which added or updated to the blob) to the DotNet Azure function. For example, when analyzing the following source code:

		[FunctionName("BlobTriggerCSharp")]        
		public static void Run([BlobTrigger("sample-container/{name}")] Stream myBlob, string name, ILogger log)
		{
		    log.LogInformation($"C# Blob trigger function Processed blob\n Name:{name} \n Size: {myBlob.Length} Bytes");
		}   

You will get the following result:

Input Binding

Supported API methods (#In-Process - Microsoft.Azure.WebJobs)

Link created

Caller type

Callee type

Blob

useSelectLinkC# MethodDotNet Azure Blob Container

For example: [Blob("samples-workitems/{queueTrigger}", FileAccess.Read)] 

Supported API methods (#Isolated - Microsoft.Azure.Functions.Worker)

Link created

Caller type

Callee type

BlobInput

useSelectLinkC# MethodDotNet Azure Blob Container

Is used to get access to a blob. From a C# Method, we create a useSelectLink to the blob object.

Output Binding

Supported API methods (#In-Process - Microsoft.Azure.WebJobs)

Link created

Caller type

Callee type

Blob

useUpdateLink C# MethodDotNet Azure Blob Container

For example: [Blob("samples-workitems-out/{queueTrigger}", FileAccess.Write)]

Supported API methods (#Isolated - Microsoft.Azure.Functions.Worker)


Link created

Caller type

Callee type

BlobOutput

useUpdateLink C# MethodDotNet Azure Blob Container

Is used to update a blob. From a C# Method, we create a useUpdateLink to the blob object. Example for Blob Input and Output Binding, when analyzing the following source code:

		[Function("BlobFunction")]
	    [BlobOutput("test-samples-output/{name}-output.txt")]
	    public static string Run(
	        [BlobTrigger("test-samples-trigger/{name}")] string myTriggerItem,
	        [BlobInput("test-samples-input/sample1.txt")] string myBlob,
	        FunctionContext context)
	    {
	        var logger = context.GetLogger("BlobFunction");
	        logger.LogInformation($"Triggered Item = {myTriggerItem}");
	        logger.LogInformation($"Input Item = {myBlob}");

	        // Blob Output
	        return "blob-output content";
	    }

You will get the following result:

CosmosDB trigger and binding

CosmosDB trigger

Supported API methods (#In-Process - Microsoft.Azure.WebJobs, #Isolated - Microsoft.Azure.Functions.Worker)

Link created

Caller type

Callee type

CosmosDBTrigger 

callLinkC# MethodDotNet Azure function

Whenever a file is added or updated to a CosmosDB collection the azure function will be executed. We add the property 'CAST_Azure_Function.cosmosDB_triggers' to the DotNet Azure function. The extension com.castsoftware.wbslinker will create a callLink from the method (which is added or updated to the CosmosDB collection) to the DotNet Azure function. For example, when analyzing the following source code:

	[FunctionName("CosmosTrigger")]
	public static void Run([CosmosDBTrigger(
		databaseName: "FamilyDatabase",
		collectionName: "FamilyCollection",
		ConnectionStringSetting = "CosmosDBConnection",
		LeaseCollectionName = "leases",
		CreateLeaseCollectionIfNotExists = true)]IReadOnlyList<Document> documents,
		ILogger log)
	{
		if (documents != null && documents.Count > 0)
		{
			log.LogInformation($"Documents modified: {documents.Count}");
			log.LogInformation($"First document Id: {documents[0].Id}");
		}
    }

You will get the following result:

Input Binding

ProcessSupported API methodsLink createdCaller typeCallee type
#In-Process - Microsoft.Azure.WebJobcosmosDBuseSelectLinkC# MethodDotNet CosmosDB collection
#Isolated - Microsoft.Azure.Functions.WorkercosmosDBInputuseSelectLinkC# MethodDotNet CosmosDB collection

Is used to get access to a CosmosDB collection. From a C# Method, we create a useSelectLink to the CosmosDB collection object.

		[FunctionName("DocByIdFromJSON")]
        public static void Run(
            [QueueTrigger("todoqueueforlookup")] ToDoItemLookup toDoItemLookup,
            [CosmosDB(
                databaseName: "ToDoItems",
                collectionName: "Items",
                ConnectionStringSetting = "CosmosDBConnection",
                Id = "{ToDoItemId}",
                PartitionKey = "{ToDoItemPartitionKeyValue}")]ToDoItem toDoItem,
            ILogger log)
        {
            log.LogInformation($"C# Queue trigger function processed Id={toDoItemLookup?.ToDoItemId} Key={toDoItemLookup?.ToDoItemPartitionKeyValue}");

            if (toDoItem == null)
            {
                log.LogInformation($"ToDo item not found");
            }
            else
            {
                log.LogInformation($"Found ToDo item, Description={toDoItem.Description}");
            }
        }

Output Binding

ProcessSupported API methodsLink createdCaller typeCallee type
#In-Process - Microsoft.Azure.WebJobscosmosDBuseUpdateLink C# MethodDotNet CosmosDB collection
#Isolated - Microsoft.Azure.Functions.WorkercosmosDBOutputuseUpdateLink C# MethodDotNet CosmosDB collection

Is used to update a CosmosDB collection. From a C# Method, we create a useUpdateLink to the CosmosDB collection object. The following code:

		[FunctionName("WriteDocsIAsyncCollector")]
        public static async Task Run(
            [QueueTrigger("todoqueueforwritemulti")] ToDoItem[] toDoItemsIn,
            [CosmosDB(
                databaseName: "ToDoItems",
                collectionName: "Items",
                ConnectionStringSetting = "CosmosDBConnection")]
                IAsyncCollector<ToDoItem> toDoItemsOut,
            ILogger log)
        {
            log.LogInformation($"C# Queue trigger function processed {toDoItemsIn?.Length} items");

            foreach (ToDoItem toDoItem in toDoItemsIn)
            {
                log.LogInformation($"Description={toDoItem.Description}");
                await toDoItemsOut.AddAsync(toDoItem);
            }
        }

Will give the following result:

Support Azure Event Hubs Trigger and Binding Output

Event Hubs can be used as a trigger or as an output binding for Azure function. For the trigger, we create a DotNet Azure Event Hub Receiver object with a call link to the Azure Function object. For output binding, the Java function sends events to a Event Hub. We create a DotNet Azure Event Hub Publisher object with a callLink to that object from the handler of function.

Supported API methods (Microsoft.Azure.WebJobs, Microsoft.Azure.Functions.Worker)

Object created (Caller)

Link created

Callee type

EventHubTrigger

DotNet Azure Event Hub Receiver / DotNet Azure Unknown Event Hub ReceivercallLinkAzure Function

Supported API methods (Microsoft.Azure.WebJobs)

Caller type

Link created

Object created (Callee)

EventHub

C# MethodcallLinkDotNet Azure Event Hub Publisher / DotNet Azure Unknown Event Hub Publisher

Supported API methods (Microsoft.Azure.Functions.Worker)

Caller type

Link created

Object created (Callee)

EventHubOutput

C# MethodcallLinkDotNet Azure Event Hub Publisher / DotNet Azure Unknown Event Hub Publisher

For example, when analyzing the following source code:

		[Function("EventHubsFunction")]
		[EventHubOutput("dest", Connection = "EventHubConnectionAppSetting")]
		public static string Run([EventHubTrigger("src", Connection = "EventHubConnectionAppSetting")] string[] input,
		    FunctionContext context)
		{
		    var logger = context.GetLogger("EventHubsFunction");

		    logger.LogInformation($"First Event Hubs triggered message: {input[0]}");

		    var message = $"Output message created at {DateTime.Now}";
		    return message;
		}

you will get the following result:

Support SignalR Trigger

Trigger the Function when clients invoke a Hub method or clients connect/disconnect SignalR. We create a DotNet Azure SignalR Hub Method object with a call link to the Azure Function object. 

Supported API methods InProcess - Microsoft.Azure.WebJobs.Extensions.SignalRService (traditional model and class-based model), Isolated - Microsoft.Azure.Functions.Worker.Extensions.SignalRService

Object created (Caller)

Link created

Callee type

SignalRTriggerAttribute

DotNet Azure SignalR Hub Method / DotNet Azure Unknown SignalR Hub MethodcallLinkAzure Function

For example, when analyzing the following source code:

		[FunctionName("broadcast")]
        public static async Task Broadcast(
        	[SignalRTrigger("HubName", "messages", "SendMessage", parameterNames: new string[] {"message"})]InvocationContext invocationContext, string message, ILogger logger)
        {
            ...
        }

You will get the following result:

Azure WebJobs support

Click here to expand...

Like Azure Functions, Azure App Service WebJobs with the WebJobs SDK is aintegration service.  We support the API for WebJobs in .NET: Microsoft.Azure.WebJob.

The azure WebJobs can be configured to be triggered or to interact with some other Azure services. Triggers cause a function to run. Binding to a function is a way of declaratively connecting another resource to the function; bindings may be connected as input bindingsoutput bindings, or both. Data from bindings is provided to the function as parameters. The following table lists the supported interactions:

Interactions

trigger

input

output

Service Bus(tick)-(tick)
Blob(tick)(tick)(tick)
CosmosDB(tick)(tick)(tick)
Event Hubs(tick)-(tick)

Detailed support for each of these interactions is given in the following sections.

Function name

In a WebJobs, the method (handler) name of a function is the function name.

Object created (Caller)

Link created

Callee type

Dotnet Azure WebJobscallLinkC# Method

Azure Service Bus Trigger and Binding Output

For the trigger, we create a DotNet Azure Service Bus Receiver object with a call link to Azure WebJobs object.

Supported API methods Microsoft.Azure.WebJobs

Object created (Caller)

Link created

Callee type

ServiceBusTrigger

DotNet Azure Service Bus Receiver or DotNet Azure Unknown Service Bus ReceivercallLinkAzure WebJobs

Supported API methods Microsoft.Azure.WebJobs

Object created (Caller)

Link created

Callee type

ServiceBusTrigger

DotNet Azure Service Bus Receiver or DotNet Azure Unknown Service Bus ReceivercallLinkAzure WebJobs

For output binding, the DotNet function sends a message to a Topic or a Queue. We create a DotNet Azure Service Bus Publisher object with a callLink to that object from the handler of WebJobs.

Supported API methods Microsoft.Azure.WebJob

Object created (Callee)

Link created

Caller type

ServiceBusDotNet Azure Service Bus Publisher or DotNet Azure Unknown Service Bus PublishercallLinkC# Method

For example, when analyzing the following source code:

		// Passes a service bus message from a queue to another queue using strings
        public static void SBQueue2SBQueue(
            [ServiceBusTrigger(StartQueueName)] string start,
            [ServiceBus(QueueNamePrefix + "1")] out string message,
            TextWriter log)
        {
            message = start + "-SBQueue2SBQueue";
            log.WriteLine("SBQueue2SBQueue: " + message);
        }

You will get the following result:

Azure Blob Trigger and Binding

Blob trigger

Supported API methods Microsoft.Azure.WebJobs

Link created

Caller type

Callee type

BlobTrigger 

callLinkC# MethodDotNet Azure WebJobs

Whenever a file is added or updated to a blob container the azure WebJobs will be executed. We add the property 'CAST_Azure_WebJobs.blob_triggers' to the DotNet Azure WebJobs. The extension com.castsoftware.wbslinker will create a callLink from the method (which added or updated to the blob) to the DotNet Azure WebJobs.

For example, when analyzing the following source code:

		public static void FailAlways(
            [BlobTrigger("badcontainer/{name}")] string message, 
            TextWriter log)
        {
            log.WriteLine("When we reach 5 retries, the message will be moved into the badqueue-poison queue");

            throw new InvalidOperationException("Simulated failure");
        }

You will get the following result:

Input Binding

Supported API methods Microsoft.Azure.WebJobs

Link created

Caller type

Callee type

Blob

useSelectLinkC# MethodDotNet Azure Blob Container

For example: [Blob("samples-workitems/{queueTrigger}", FileAccess.Read)] Is used to get access to a blob. From the handler Method, we create a useSelectLink to the blob object. For example, when analyzing the following source code:

		public static async Task BlobBindingInput(
            [QueueTrigger("persons")] Person persons,
            string Name,
            [Blob("persons/{Name}BlobBindingInput", FileAccess.Read)] Stream input)
        {
            ...
        }

You will get the following result:

Output Binding

Supported API methods Microsoft.Azure.WebJobs

Link created

Caller type

Callee type

Blob

useUpdateLink C# MethodDotNet Azure Blob Container

For example: [Blob("samples-workitems-out/{queueTrigger}", FileAccess.Write)] Is used to update a blob. From the handler Method, we create a useUpdateLink to the blob object. For example, when analyzing the following source code:

 		public static async Task BlobNameFromQueueMessage(            
            string Name,
            [Blob("persons/{Name}BlobNameFromQueueMessage", FileAccess.Write)] Stream output)
        {
            byte[] messageBytes = Encoding.UTF8.GetBytes("Hello " + Name);

            await output.WriteAsync(messageBytes, 0, messageBytes.Length);
        }

You will get the following result:

CosmosDB trigger and binding

CosmosDB trigger

Supported API methods Microsoft.Azure.WebJobs

Link created

Caller type

Callee type

CosmosDBTrigger 

callLinkC# MethodDotNet Azure WebJobs

Whenever a file is added or updated to a CosmosDB collection the azure WebJobs will be executed. We add the property 'CAST_Azure_WebJobs.cosmosDB_triggers' to the DotNet Azure WebJobs. The extension com.castsoftware.wbslinker will create a callLink from the method (which is added or updated to the CosmosDB collection) to the DotNet Azure WebJobs. 

For example, when analyzing the following source code:

 		public static void Run([CosmosDBTrigger(
            databaseName: "FamilyDatabase",
            collectionName: "FamilyCollection",
            ConnectionStringSetting = "CosmosDBConnection",
            LeaseCollectionName = "leases",
            CreateLeaseCollectionIfNotExists = true)]IReadOnlyList<Document> documents,
            ILogger log)
        {
            if (documents != null && documents.Count > 0)
            {
                log.LogInformation($"Documents modified: {documents.Count}");
                log.LogInformation($"First document Id: {documents[0].Id}");
    	    }
    	}

You will get the following result:

Input Binding

Supported API methods Microsoft.Azure.WebJob

Link created

Caller type

Callee type

cosmosDBuseSelectLinkC# MethodDotNet CosmosDB collection

Is used to get access to a CosmosDB collection. From the handler Method, we create a useSelectLink to the CosmosDB collection object. For example, when analyzing the following source code:

		public static void Run(
            [QueueTrigger("todoqueueforlookup")] ToDoItemLookup toDoItemLookup,
            [CosmosDB(
                databaseName: "ToDoItems",
                collectionName: "Items",
                ConnectionStringSetting = "CosmosDBConnection",
                Id = "{ToDoItemId}",
                PartitionKey = "{ToDoItemPartitionKeyValue}")]ToDoItem toDoItem,
            ILogger log)
        {
            log.LogInformation($"C# Queue trigger function processed Id={toDoItemLookup?.ToDoItemId} Key={toDoItemLookup?.ToDoItemPartitionKeyValue}");

            if (toDoItem == null)
            {
                log.LogInformation($"ToDo item not found");
            }
            else
            {
                log.LogInformation($"Found ToDo item, Description={toDoItem.Description}");
            }
        }

You will get the following result:

Output Binding

Supported API methods Microsoft.Azure.WebJobs

Link created

Caller type

Callee type

cosmosDBuseUpdateLink C# MethodDotNet CosmosDB collection

Is used to update a CosmosDB collection. From the handler Method, we create a useUpdateLink to the CosmosDB collection object. For example, when analyzing the following source code:

		public static async Task Run(            
            [CosmosDB(
                databaseName: "ToDoItems",
                collectionName: "Items",
                ConnectionStringSetting = "CosmosDBConnection")]
                IAsyncCollector<ToDoItem> toDoItemsOut,
            ILogger log)
        {
            log.LogInformation($"C# Queue trigger function processed {toDoItemsIn?.Length} items");

            foreach (ToDoItem toDoItem in toDoItemsIn)
            {
                log.LogInformation($"Description={toDoItem.Description}");
                await toDoItemsOut.AddAsync(toDoItem);
            }
        }

You will get the following result:

Durable Functions

Durable Functions allow calling an azure WebJobs from another azure WebJobs.

Supported API methods (Microsoft.Azure.WebJobs)

Object created (Callee)Link createdCaller

DurableOrchestrationClientBase.StartNewAsync 

DurableOrchestrationContextBase.CallSubOrchestratorAsync

DurableOrchestrationContextBase.CallSubOrchestratorWithRetryAsync

DurableOrchestrationContextBase.StartNewOrchestration

DurableOrchestrationContextBase.CallActivityAsync 

DurableOrchestrationContextBase.CallActivityWithRetryAsync

DotNet Call to Azure WebJobs or DotNet Call to Azure Unknown WebJobscallLinkC# Method

The extension com.castsoftware.wbslinker will match DotNet Call to Azure WebJobs objects to Azure WebJobs objects such as DotNet Azure WebJobs. For example, when analyzing the following source code:

		public static async Task CronJob(           
            [OrchestrationClient] DurableOrchestrationClient client,
            ILogger logger)
        {
            logger.LogInformation("Cron job fired!");

            string instanceId = await client.StartNewAsync('HelloSequence', input: null);
            logger.LogInformation($"Started new instance with ID = {instanceId}.");
			...
           
        }

        public static async Task<List<string>> HelloSequence(
            [OrchestrationTrigger] DurableOrchestrationContextBase context)
        {
            var outputs = new List<string>();

            outputs.Add(await context.CallActivityAsync<string>('SayHello', "Tokyo"));
            outputs.Add(await context.CallActivityAsync<string>('SayHello', "Seattle"));
            outputs.Add(await context.CallActivityAsync<string>('SayHello', "London"));

            // returns ["Hello Tokyo!", "Hello Seattle!", "Hello London!"]
            return outputs;
        }

        public static string SayHello([ActivityTrigger] string name, ILogger logger)
        {
            string greeting = $"Hello {name}!";
            logger.LogInformation(greeting);
            Thread.Sleep(5000);
            return greeting;
        }

You will get the following result:

Manual trigger

To trigger the following function manually: 

		[NoAutomaticTrigger]
		public static void CreateQueueMessage(
		ILogger logger,
		string value,
		[Queue("outputqueue")] out string message)
		{
		    message = value;
		    logger.LogInformation("Creating queue message: ", message);
		}

For version 3.x:

Supported API methods (Microsoft.Azure.WebJobs)

Object created (Callee)Link createdCaller

JobHost.CallAsync

DotNet Call to Azure WebJobs or DotNet Call to Azure Unknown WebJobscallLinkC# Method

When analyzing the following source code:

		static async Task Main(string[] args)
    	{
    	    var builder = new HostBuilder();
    	    builder.ConfigureWebJobs(b =>
    	    {
    	        b.AddAzureStorageCoreServices();
    	        b.AddAzureStorage();
    	    });
    	    var host = builder.Build();
    	    using (host)
    	    {
    	        var jobHost = host.Services.GetService(typeof(IJobHost)) as JobHost;
    	        var inputs = new Dictionary<string, object>
    	        {
    	            { "value", "Hello world!" }
    	        };

    	        await host.StartAsync();
    	        await jobHost.CallAsync("CreateQueueMessage", inputs);
    	        await host.StopAsync();
    	    }
    	}

For version 2.x:

Supported API methods (Microsoft.Azure.WebJobs)

Object created (Callee)Link createdCaller

JobHost.Call

DotNet Call to Azure WebJobs or DotNet Call to Azure Unknown WebJobscallLinkC# Method

When analyzing the following source code:

		static void Main(string[] args)
    	{
    	    JobHost host = new JobHost();
    	    host.Call(typeof(Program).GetMethod("CreateQueueMessage"), new { value = "Hello world!" });
    	}

In both cases, you will give the following result:

Support Azure Event Hubs Trigger and Binding Output

Event Hubs can be used as a trigger or as an output binding for Azure WebJobs. For the trigger, we create a DotNet Azure Event Hub Receiver object with a call link to the Azure WebJobs object. For output binding, the Java Webjobs sends events to a Event Hub. We create a DotNet Azure Event Hub Publisher object with a callLink to that object from the handler of webjobs.

Supported API methods (Microsoft.Azure.WebJobs)

Object created (Caller)

Link created

Callee type

EventHubTrigger

DotNet Azure Event Hub Receiver / DotNet Azure Unknown Event Hub Receiver

callLink

Azure WebJobs 

Supported API methods (Microsoft.Azure.WebJobs)

Caller type

Link created

Object created (Callee)

EventHub

C# Method

callLink

DotNet Azure Event Hub Publisher / DotNet Azure Unknown Event Hub Publisher

For example, when analyzing the following source code:

		public void Run(
		    [EventHubTrigger("source", Connection = "EventHubConnectionAppSetting")] EventData myEventHubMessage,
			[EventHub("dest", Connection = "EventHubConnectionAppSetting")]IAsyncCollector<string> outputEvents,
		    DateTime enqueuedTimeUtc,
		    Int64 sequenceNumber,
		    string offset,
		    ILogger log)
		{
		    log.LogInformation($"Event: {Encoding.UTF8.GetString(myEventHubMessage.Body)}");
		    // Metadata accessed by binding to EventData
		    log.LogInformation($"EnqueuedTimeUtc={myEventHubMessage.SystemProperties.EnqueuedTimeUtc}");
		    log.LogInformation($"SequenceNumber={myEventHubMessage.SystemProperties.SequenceNumber}");
		    log.LogInformation($"Offset={myEventHubMessage.SystemProperties.Offset}");
		    // Metadata accessed by using binding expressions in method parameters
		    log.LogInformation($"EnqueuedTimeUtc={enqueuedTimeUtc}");
		    log.LogInformation($"SequenceNumber={sequenceNumber}");
		    log.LogInformation($"Offset={offset}");
		}

you will get the following result:

Azure SignalR Service

Click here to expand...

Server side

Define methods that can be called by clients. For each method in Hub class of server, we create DotNet Azure SignalR Hub Method where the object name is the name of hub method.  Add a property hub_Name to save the hub name when the Hub class is instantiated.

Supported API methods - latest package: Microsoft.AspNetCore.SignalR, Microsoft.AspNetCore.Builder

Object created

Link created

Callee type

SignalR.Hub

Builder.HubEndpointRouteBuilderExtensions.MapHub

SignalR.HubRouteBuilder.MapHub

DotNet Azure SignalR Hub Method / DotNet Azure Unknown SignalR Hub Method

callLink

C# Method

Supported API methods - old package: Microsoft.AspNet.SignalR

Object created

Link created

Callee type

SignalR.Hub

Owin.OwinExtensions.MapAzureSignalR 

System.Web.Routing.SignalRRouteExtensions.MapHubs

DotNet Azure SignalR Hub Method / DotNet Azure Unknown SignalR Hub Method

callLink

C# Method

For example, when analyzing the following source code to define Hub class:

	public class ChatHub : Hub
    {
    	
        public async Task SendMessage(string name, string message)
        {            
            await Clients.All.SendAsync("ReceiveMessage", name, message);           
        }
    	
    	public async Task AddGroup(string name, string message)
        {
    		 await Groups.AddToGroupAsync(Context.ConnectionId, "SignalR Users");
        }
    	
    	public override async Task OnConnectedAsync()
    	{
    	    
    	    await base.OnConnectedAsync();
    	}
    	
    	public override async Task OnDisconnectedAsync(Exception? exception)
    	{
    	    await base.OnDisconnectedAsync(exception);
    	}
    }

and the following source code to configure SignalR URL connection:

			app.UseEndpoints(endpoints =>
            {
                endpoints.MapHub<ChatHub>("/HubName");
            });

you will get the following result where all DotNet Azure SignalR Hub Method objects have a hub_name property as 'HubName':

Support change hub method name for latest package

Support Microsoft.AspNetCore.SignalR.HubMethodNameAttribute to set the correct object name for DotNet Azure SignalR Hub Method object

Support change hub class name for old package

Support Microsoft.AspNet.SignalR.Hubs.HubNameAttribute to set the correct hub_name property value for DotNet Azure SignalR Hub Method object

Client side

Call methods that run on the server. When there is an API method which invokes a hub method, we create a DotNet Azure SignalR Call to Hub Method object where the object name is the name of invoked hub method. Add a property hub_Name to save the hub name which is connected by this client.

Supported API methods - latest package: Microsoft.AspNetCore.SignalR.Client

Object created

Link created

Caller type

Client.HubConnectionExtensions.InvokeAsync

Client.HubConnectionExtensions.InvokeCoreAsync

Client.HubConnection.StartAsync 

Client.HubConnection.StopAsync 

DotNet Azure SignalR Call to Hub Method / DotNet Azure SignalR Call to Unknown Hub Method

callLink

C# Method

Supported API methods - old package: Microsoft.AspNet.SignalR.Client

Object created

Link created

Caller type

Hubs.IHubProxy.Invoke

Connection.Start

Connection.Stop

DotNet Azure SignalR Call to Hub Method / DotNet Azure SignalR Call to Unknown Hub Method

callLink

C# Method

The extension com.castsoftware.wbslinker will match DotNet Azure SignalR Call to Hub Method objects to DotNet Azure SignalR Hub Method in server side. For example, when analyzing the following source code in client side:

	private async void sendButton_Click(object sender, RoutedEventArgs e)
        {
            #region snippet_ErrorHandling
            try
            {
                #region snippet_InvokeAsync
                await connection.InvokeAsync("SendMessage", 
                    userTextBox.Text, messageTextBox.Text);
                #endregion
            }
			...

and if your source code contains a corresponding DotNet Azure SignalR Hub Method with the same name in server side, you will get the following result:

Objects

The following objects are resolved:

IconDescriptionEntry PointEnd PointData Entity

Dotnet Azure Blob Container

(tick)

Dotnet Azure Unknown Blob Container

(tick)

DotNet Azure Service Bus Receiver

(tick)

(only when not called by other objects)



DotNet Azure Unknown Service Bus Receiver(tick)



DotNet Azure Service Bus Publisher

(tick) 

(only when it is not calling any other object)


DotNet Azure Unknown Service Bus Publisher
(tick)

DotNet Azure Event Hub Receiver

(tick)

(only when not called by other objects)



DotNet Azure Unknown Event Hub Receiver(tick)



DotNet Azure Event Hub Publisher

(tick) 

(only when it is not calling any other object)


DotNet Azure Unknown Event Hub Publisher
(tick)

DotNet Azure Function

(tick)

(only when not called by other objects)



DotNet Azure Unknown Function(tick)

DotNet Call to Azure Function

(tick) 

(only when it is not calling any other object)


DotNet Call to Azure Unknown Function
(tick)

DotNet Azure Get Operation

(tick)

(only when not called by other objects)



DotNet Azure Post Operation

(tick)

(only when not called by other objects)



DotNet Azure Put Operation

(tick)

(only when not called by other objects)



DotNet  Azure Delete Operation

(tick)

(only when not called by other objects)



DotNet Azure Any Operation

(tick)

(only when not called by other objects)




DotNet Azure WebJobs

(tick)

(only when not called by other objects)




DotNet Call to Azure WebJobs

(tick) 

(only when it is not calling any other object)



DotNet Call to Azure Unknown WebJobs
(tick)

DotNet Azure SignalR Hub Method

(tick)

(only when not called by other objects)



DotNet Azure Unknown SignalR Hub Method(tick)

DotNet Azure SignalR Call to Hub Method

(tick) 

(only when it is not calling any other object)


DotNet Azure SignalR Call to Unknown Hub Method
(tick) 

Known Limitations

  • For the support of Azure Function and Azure WebJobs, currently the parameter values inside annotations in some cases cannot be resolved.