Hey <#CQ2QFLNFL|dotnet> folk. We've just released ...
# dotnet
e
Hey #dotnet folk. We've just released a first look at the custom provider API for dotnet. This will let you write your own resource providers in C# instead of Go. See the blog post at https://www.pulumi.com/blog/dotnet-custom-providers/
w
Each provider has its own output. How could I use the out put of custom resources from the above sample? Seems it is missing the arguments and output sample.
e
You'd need to generate SDKs for the provider, the same as for when writing a Go provider. If you build a provider binary from this SDK and return a schema from the GetSchema method then
pulumi package gen-sdk <provider.exe> --language dotnet
should generate a dotnet sdk.
w
seems, It is not straightforward to develop a provider with C#. I think I should wait for the end-to-end guideline instead. 🙏 🙏 🙏
Seems, I got confused between Custom Provider and Dynamic Resource Provider. https://www.pulumi.com/docs/intro/concepts/resources/dynamic-providers/ Currently, I have some DRP in TypeScript and would like to convert to C#, However, this feature is not supported in C# yet.
e
Currently, I have some DRP in TypeScript and would like to convert to C#, However, this feature is not supported in C# yet.
Yes, we're looking into this. We're also looking at making custom providers easier to use such that you could also just use side by side custom providers with your programs, avoiding the magic of dynamic providers (they have to do function serialisation, which when it works is very cool, and when it doesn't work is a pain to fix)
w
HI, @echoing-dinner-19531 Just would like to follow up on this. Are there any solutions found for dynamic providers with C# as I would like to migrate all NodeJs code to C#. I asked the Pulumi AI and it showed me this code. Is it work?
Copy code
using System.Collections.Immutable;
using System.Threading.Tasks;
using Pulumi;

class MyStack : Stack
{
    public MyStack()
    {
        var myDynamicResource = new MyCustomResource("myDynamicResource", new InputMap
        {
            { "param1", "value1" },
            { "param2", "value2" },
        });

        this.ResourceOutput = myDynamicResource.Outputs.Apply(outputs => outputs["myOutput"].ToString());
    }

    [Output]
    public Output<string> ResourceOutput { get; set; }
}

public class MyCustomResource : Pulumi.DynamicResource
{
    public MyCustomResource(string name, InputMap args, ComponentResourceOptions? options = null)
        : base(new MyDynamicResourceProvider(), name, args, options)
    {
    }
}

public class MyDynamicResourceProvider : Pulumi.DynamicResourceProvider
{
    public override async Task<ImmutableDictionary<string, object>> CreateAsync(CreateArgs args)
    {
        // Write your custom logic to perform actions on the platform you want to create resources on.
        var result = ImmutableDictionary<string, object>.Empty.Add("myOutput", "output_value");
        return result;
    }

    public override Task DiffAsync(DiffArgs args)
    {
        // Write your custom logic to compare the differences between the old and new state and return a diff result.
        return Task.FromResult(new DiffResult());
    }

    public override Task DeleteAsync(DeleteArgs args)
    {
        // Write your custom logic to clean up your resources delete the resource.
        return Task.CompletedTask;
    }

    public override Task<ImmutableDictionary<string, object>> UpdateAsync(UpdateArgs args)
    {
        // Write your custom logic to update your resource based on the changes.
        var result = args.Inputs;
        return Task.FromResult(result);
    }

    public override Task<DependencyPropertyValue> GetAsync(GetArgs args)
    {
        // Write your custom logic to fetch the resource state based on the inputs.
        return Task.FromResult(new DependencyPropertyValue(default));
    }
}
e
Are there any solutions found for dynamic providers with C# as I would like to migrate all NodeJs code to C#.
Well I've had this sitting around for a while, and I can't give it as an official supported Pulumi thing but, just got it published on my personal account: https://www.nuget.org/packages/Ibasa.Pulumi.Dynamic/ Example:
Copy code
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Pulumi;
using Pulumi.Experimental.Provider;
using Ibasa.Pulumi.Dynamic;

await Deployment.RunAsync(() =>
{
    var args = new SomeDynamicArgs()
    {
        Value = "hello world"
    };

    var d = new SomeDynamicResource("my-resource", args);

    return new Dictionary<string, object?>() {
        {
            "Count", d.Result
        }
    };
});


sealed class SomeDynamicResourceProvider : DynamicProvider
{
    public override Task<CreateResponse> Create(CreateRequest request, CancellationToken ct)
    {
        if (request.Type == "dotnet-dynamic:index:SomeDynamicResource")
        {
            if (!request.Properties["value"].TryGetString(out var valueString))
            {
                throw new Exception("value should be a string");
            }

            var properties = new Dictionary<string, PropertyValue>
            {
                { "result", new PropertyValue(valueString!.Length) }
            };

            return Task.FromResult(new CreateResponse()
            {
                Id = valueString,
                Properties = properties,
            });
        }
        throw new Exception("Unknown resource type: " + request.Type);
    }

    public override Task<UpdateResponse> Update(UpdateRequest request, CancellationToken ct)
    {
        if (request.Type == "dotnet-dynamic:index:SomeDynamicResource")
        {
            if (!request.News["value"].TryGetString(out var valueString))
            {
                throw new Exception("value should be a string");
            }

            var properties = new Dictionary<string, PropertyValue>
            {
                { "result", new PropertyValue(valueString!.Length) }
            };

            return Task.FromResult(new UpdateResponse()
            {
                Properties = properties,
            });
        }
        throw new Exception("Unknown resource type: " + request.Type);
    }
}

sealed class SomeDynamicArgs : DynamicResourceArgs
{
    [Input("value", required: true)]
    public Input<string> Value { get; set; } = null!;
}

sealed class SomeDynamicResource : DynamicResource<SomeDynamicArgs>
{
    private static SomeDynamicResourceProvider provider = new SomeDynamicResourceProvider();

    public SomeDynamicResource(string name, SomeDynamicArgs? args = null, CustomResourceOptions? options = null)
        : base(provider, name, args, options, null, "SomeDynamicResource")
    {
    }

    [Output("result")]
    public Output<int> Result { get; set; } = null!;
}