# .NET Core

## Getting and publishing a function

The following shows how to get, edit, and pack your template for upload.

| Versions      | Template                                                                                            |
| ------------- | --------------------------------------------------------------------------------------------------- |
| .NET Core 2.1 | [Download](https://codemash-public.s3.eu-central-1.amazonaws.com/code-templates/dotnetcore_2_1.zip) |

* After you have downloaded the template project, unzip it and navigate to `./LambdaFunction` directory and open `LambdaFunction.csproj` project (if you are not using an IDE with automated restore functionality, run `dotnet restore` in command-line tool inside this folder).
* Your entry (main) method will be inside `Function.cs` file called `Handler`.
* After you are done editing your function, open command-line tool inside of `./LambdaFunction`

  &#x20;directory and run`dotnet publish -o lambda`.
* Navigate to a newly created folder `./lambda` and zip all the contents inside of the directory.
* Upload zipped file to CodeMash.

For the **handler,** you have to specify your entry function location. Handler follows such format - `assembly::namespace.className::methodName`. Following the structure given in the initial template, the handler would be `LambdaFunction::LambdaFunction.Function::Handler`. You can edit any of these parameters for your own function.

## Template overview

The following explains how to use provided template to create your own functions.

### Main method

You define your main function in the handler field. In this case, the main method is `Handler`. It takes two parameters - input from CodeMash and function configuration.

```csharp
public async Task<APIGatewayProxyResponse> Handler(CustomEventRequest<BasicInput> lambdaEvent, ILambdaContext context)
{
    ...
}
```

### Inputs

CodeMash will always return `CustomEventRequest` as an input object. This class takes in generic parameter defining one of the possible input type. The following table explains when to use each of the provided inputs.

| Class                    | Description                                                                         |
| ------------------------ | ----------------------------------------------------------------------------------- |
| `BasicInput`             | Use when executing function through API or using this function in a scheduler task. |
| `CollectionTriggerInput` | Use when using this function as a trigger for collections.                          |
| `FileTriggerInput`       | Use when using this function as a trigger for files.                                |
| `UserTriggerInput`       | Use when using this function as a trigger for users.                                |

### Getting environment variables

A line below shows how to get the environment variables that you have set up near your function.

```csharp
var envVariable = Environment.GetEnvironmentVariable("myVariableName");
```

### Getting app settings

If you want to user`appsettings.json`file the following shows how to read a file. In this case, file is in root directory of a project.

```csharp
public static class AppSettings
{
    private static IConfigurationRoot instance;

    // Method to get a string from settings
    public static string GetString(string key)
    {
        if (instance == null)
        {
            // Create an instance with settings
            instance = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json")
                .Build();
        }
        
        // Get value by key
        return instance[key];
    }
}
```

Example of a `appsettings.json` file:

```csharp
{
    "Parameter1": "First parameter.",
    "NestedParams": {
        "NestedParam1": "First nested parameter."
    }
}
```

Then to get a string from settings:

```csharp
// First level parameter
var settings = AppSettings.GetString("Parameter1");

// Second level parameter
var nestedSettings = AppSettings.GetString("NestedParams:NestedParam1");
```

### Constructors

Lambda executor will call your default constructor (without parameters). If you want to add dependency injection to your services, you will have to add a default constructor which calls your wanted constructor.

```csharp
public class Function
{
    private readonly IExampleService _exampleService;
    
    // (Required if adding other constructors. Otherwise, optional.) A default constructor
    // called by Lambda. If you are adding your custom constructors,
    // default constructor with no parameters must be added
    public Function() : this (new ExampleService()) {}

    // (Optional) An example of injecting a service. As a default constructor is called by Lambda
    // this constructor has to be called from default constructor
    public Function(IExampleService exampleService)
    {
        _exampleService = exampleService;
    }
    
    public async Task<APIGatewayProxyResponse> Handler(CustomEventRequest<BasicInput> lambdaEvent, ILambdaContext context)
    {
        ...
        
        // - Call example service
        var helloWorldMessage = await _exampleService.GetHelloWorld();
        
        ...
    }
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.codemash.io/dashboard/code/functions/function-templates/.net-core.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
