# Use .NET and NuGet

> Call CLR APIs, restore NuGet packages, reference C# projects, and consume Alice from C#.

Canonical: https://alice-lang.org/documentation/guides/dotnet/

[Documentation index](https://alice-lang.org/documentation/llms.txt) · [Complete book](https://alice-lang.org/llms-full.txt)

## Call a .NET API

Alice types are CLR types. Import a namespace, construct an object with `.new`, and call its declared members.

```alice
using System.Text
builder = StringBuilder.new
builder.Append("Alice")
builder.Append(" on .NET")
puts builder.ToString()
puts Math.Sqrt(81.0)
```

Expected output:

```text
Alice on .NET
9
```

[Edit and run in the Alice playground](https://playground.alice-lang.org/#code=u.dXNpbmcgU3lzdGVtLlRleHQKYnVpbGRlciA9IFN0cmluZ0J1aWxkZXIubmV3CmJ1aWxkZXIuQXBwZW5kKCJBbGljZSIpCmJ1aWxkZXIuQXBwZW5kKCIgb24gLk5FVCIpCnB1dHMgYnVpbGRlci5Ub1N0cmluZygpCnB1dHMgTWF0aC5TcXJ0KDgxLjAp)

The compiler binds .NET calls with Roslyn and reports errors against the Alice source. You can use the BCL directly; there is no separate Alice wrapper required for `StringBuilder`, `Math`, `Path`, `DateTime`, or framework APIs.

## Add a NuGet package

From an Alice project:

```sh
alice add Newtonsoft.Json --version '13.*'
alice install
```

Then in a source file:

```alice
using Newtonsoft.Json
record Greeting(message : String)
puts JsonConvert.SerializeObject(Greeting.new("Hello, Alice!"))
```

The package belongs in `alice.toml`, and exact restored versions belong in `alice.lock`. NuGet uses the normal .NET cache, shared with C# projects. A `using` declaration alone cannot restore a package.

## Generic APIs and callbacks

Generic types use parentheses, for example `List(Int32)`. Typed lambdas adapt to compatible delegate parameters:

```alice
puts [3, 1, 2].OrderBy(->(x : Int32) { x }).First()
```

Use .NET's declared spelling and overloads. If a lambda or generic call is ambiguous, annotate the parameter and result types rather than switching the entire API to `Any`.

`ref` and `out` arguments are supported where a .NET signature requires them. For example, initialize an integer variable and pass it to `Int32.TryParse(text, out number)`; check the Boolean result before using the parsed number.

## Reference a C# project

Add a path dependency:

```toml
[dependencies]
CSharpLib = { path = "../CSharpLib/CSharpLib.csproj" }
```

Import its namespace and call its public types normally. Build the dependency so both the compiler and language server can see its assembly. XML documentation placed beside the DLL is available to the editor.

## Call Alice from C\#

Create an Alice library with `alice new Geometry --lib`, define public records/modules, and build it. A C# project can reference the generated Alice project:

```xml
<ProjectReference Include="../Geometry/.alice/Geometry.alproj" />
```

Run an Alice build or install first to generate that file. The manifest remains authoritative; commit the Alice source and `alice.toml`, not `.alice/`. For a shared repository, use a repeatable build step to regenerate the project before C# needs it.

The [interop samples](https://github.com/alicelanguage/alice/tree/main/samples) demonstrate `AliceLib`, `AliceApp`, `CSharpLib`, and `CSharpApp` working together.

## Framework references

NuGet package references and shared-framework references are different. An ASP.NET host needs `Microsoft.AspNetCore.App` in its MSBuild settings. Use a `Directory.Build.props` beside the Alice package for additional MSBuild properties or references that the manifest does not represent. Do not hand-edit the disposable generated project.

Next, build a [web API](https://alice-lang.org/documentation/guides/web.md), or learn how to organize [workspace packages](https://alice-lang.org/documentation/tools/workspaces.md).

## Continue reading

- Previous: [Race safety and AL0202](https://alice-lang.org/documentation/concurrency/race-safety.md)
- Next: [Build a web API](https://alice-lang.org/documentation/guides/web.md)
