Skip to content

Instantly share code, notes, and snippets.

@mikhailshilkov
Last active December 18, 2019 11:06
Show Gist options
  • Save mikhailshilkov/3a1a9efaebba5eec2cbfa684ae357db1 to your computer and use it in GitHub Desktop.
Save mikhailshilkov/3a1a9efaebba5eec2cbfa684ae357db1 to your computer and use it in GitHub Desktop.
class ComponentData
{
[Output("connectionString")]
public Output<string>? ConnectionString { get; set; }
[Output("subscriptionId")]
public Output<string>? SubscriptionId { get; set; }
}
// --------------------------------------------------------------------------------------
// Option 1: No base class
// --------------------------------------------------------------------------------------
class MyComponent1 : ComponentResource
{
[Output("connectionString")]
public Output<string>? ConnectionString { get; private set; }
[Output("subscriptionId")]
public Output<string>? SubscriptionId { get; private set; }
public MyComponent1(string name) : base("my:component", name)
{
var data = Output.Create(InitializeAsync());
this.ConnectionString = data.Apply(v => v.ConnectionString);
this.SubscriptionId = data.Apply(v => v.SubscriptionId);
this.RegisterOutputs();
}
private async Task<ComponentData> InitializeAsync()
{
var resourceGroup = new ResourceGroup("appservice-rg");
var storageAccount = new Account("sa", new AccountArgs
{
ResourceGroupName = resourceGroup.Name,
AccountReplicationType = "LRS",
AccountTier = "Standard",
});
var config = await Pulumi.Azure.Core.Invokes.GetClientConfig();
return new ComponentData
{
ConnectionString = storageAccount.PrimaryConnectionString,
SubscriptionId = Output.Create(config.SubscriptionId),
};
}
}
// --------------------------------------------------------------------------------------
// Option 2: Base class
// --------------------------------------------------------------------------------------
abstract class AsyncComponentResource<TData> : ComponentResource
{
public AsyncComponentResource(string type, string name, ResourceOptions? options = null) : base(type, name, options)
{
var data = Output.Create(InitializeAsync());
this.LiftOutputs(data);
this.RegisterOutputs();
}
protected abstract Task<TData> InitializeAsync();
protected abstract void LiftOutputs(Output<TData> data);
}
class MyComponent2 : AsyncComponentResource<ComponentData>
{
[Output("connectionString")]
public Output<string>? ConnectionString { get; private set; }
[Output("subscriptionId")]
public Output<string>? SubscriptionId { get; private set; }
public MyComponent2(string name) : base("my:component", name)
{
// Not allowed to create resources here!
}
protected override async Task<ComponentData> InitializeAsync()
{
var resourceGroup = new ResourceGroup("appservice-rg");
var storageAccount = new Account("sa", new AccountArgs
{
ResourceGroupName = resourceGroup.Name,
AccountReplicationType = "LRS",
AccountTier = "Standard",
});
var config = await Pulumi.Azure.Core.Invokes.GetClientConfig();
return new ComponentData
{
ConnectionString = storageAccount.PrimaryConnectionString,
SubscriptionId = Output.Create(config.SubscriptionId),
};
}
protected override void LiftOutputs(Output<ComponentData> data)
{
this.ConnectionString = data.Apply(v => v.ConnectionString);
this.SubscriptionId = data.Apply(v => v.SubscriptionId);
}
}
// --------------------------------------------------------------------------------------
// Option 3: Base class with GetData (same as TS)
// --------------------------------------------------------------------------------------
abstract class AsyncComponentResource2<TData> : ComponentResource
{
public AsyncComponentResource2(string type, string name, ResourceOptions? options = null) : base(type, name, options)
{
}
protected Output<TData> GetData() => Output.Create(InitializeAsync());
protected abstract Task<TData> InitializeAsync();
}
class MyComponent3 : AsyncComponentResource2<ComponentData>
{
[Output("connectionString")]
public Output<string>? ConnectionString { get; }
[Output("subscriptionId")]
public Output<string>? SubscriptionId { get; }
public MyComponent3(string name) : base("my:component", name)
{
// Not allowed to create resources here!
var data = this.GetData();
this.ConnectionString = data.Apply(v => v.ConnectionString);
this.SubscriptionId = data.Apply(v => v.SubscriptionId);
this.RegisterOutputs();
}
protected override async Task<ComponentData> InitializeAsync()
{
var resourceGroup = new ResourceGroup("appservice-rg");
var storageAccount = new Account("sa", new AccountArgs
{
ResourceGroupName = resourceGroup.Name,
AccountReplicationType = "LRS",
AccountTier = "Standard",
});
var config = await Pulumi.Azure.Core.Invokes.GetClientConfig();
return new ComponentData
{
ConnectionString = storageAccount.PrimaryConnectionString,
SubscriptionId = Output.Create(config.SubscriptionId),
};
}
}
// --------------------------------------------------------------------------------------
// Option 4: Factory
// --------------------------------------------------------------------------------------
class MyComponent4 : ComponentResource
{
public static async Task<MyComponent4> Create(string name, object/*whatever proper type*/ args)
{
var config = await Pulumi.Azure.Core.Invokes.GetClientConfig();
return new MyComponent4(name, args, config.SubscriptionId);
}
[Output("connectionString")]
public Output<string>? ConnectionString { get; private set; }
[Output("subscriptionId")]
public Output<string>? SubscriptionId { get; private set; }
private MyComponent4(string name, object args, string subscriptionId) : base("my:component", name)
{
var resourceGroup = new ResourceGroup("appservice-rg");
var storageAccount = new Account("sa", new AccountArgs
{
ResourceGroupName = resourceGroup.Name,
AccountReplicationType = "LRS",
AccountTier = "Standard",
});
this.ConnectionString = storageAccount.PrimaryConnectionString;
this.SubscriptionId = Output.Create(subscriptionId);
this.RegisterOutputs();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment