Reputation: 5038
I have a block of fluent C# code:
If I knew how many disks existed the syntax would be:
var tempVM = await azure.VirtualMachines.Define(targetVMName)
.WithRegion(vm.Region)
.WithExistingResourceGroup(targetResourceGroupName)
.WithNewPrimaryNetworkInterface(nicDefinitions[0])
.WithSpecializedOSDisk(disks[0], disks[0].OSType.Value)
.WithSize(vm.Size)
.WithTags(tags)
.WithExistingDataDisk(d[0]) <<<<<<<
.WithExistingDataDisk(d[1]) <<<<<<<
.WithExistingDataDisk(d[2]) <<<<<<<
.WithExistingDataDisk(d[3]) <<<<<<<
.CreateAsync();
I may have 0 or more datadisks to add. Is there a fluent syntax to support 0 or more disks ?
Upvotes: 1
Views: 144
Reputation: 151584
Assuming this is using extension method on an interface named IWithManagedCreate
, you have this method:
public static IWithManagedCreate WithExistingDataDisk(this IWithManagedCreate vm, IDisk disk)
{
// ...
return vm;
}
You could simply add an extension method of your own with a params IDisk[]
overload:
public static IWithManagedCreate WithExistingDataDisks(this IWithManagedCreate vm, params IDisk[] disks)
{
foreach (var disk in disks)
{
vm = vm.WithExistingDataDisk(disk);
}
return vm;
}
And call it like that:
.WithTags(tags)
.WithExistingDataDisks(d) // passing the array containing 0 or more disks
.CreateAsync();
So, to answer the question, no, fluent syntax is nothing special, just a chain of method calls. When you chain method calls (by letting each method return something that you can call more methods on), you can't make them conditional; you can make a method however do nothing as demonstrated above. When you call it with an empty array, nothing happens.
Upvotes: 4
Reputation: 89036
Often in fluent API's you can use an assignment in a loop, like this:
var expTempVM = azure.VirtualMachines.Define(targetVMName)
.WithRegion(vm.Region)
.WithExistingResourceGroup(targetResourceGroupName)
.WithNewPrimaryNetworkInterface(nicDefinitions[0])
.WithSpecializedOSDisk(disks[0], disks[0].OSType.Value)
.WithSize(vm.Size)
.WithTags(tags);
foreach (var d in disks)
{
expTempVM = expTempVM.WithExistingDataDisk(d);
}
var tempVM = await expTempVM.CreateAsync();
As the basic design of a fluent API is that each method returns the same type that it operates on.
And if you can do that, you can also define your own extension method, .WithExistingDataDisks
or similar.
Upvotes: 1
Reputation: 8359
The WithExistingDataDisk
is declared in the IWithManagedDataDisk
interface.
This interface doesn't provide any method to add many existing IDisk
in one call.
Anyway, you can implement it as an extension method like this :
public static class WithManagedDataDiskExtensions
{
// allow to manually specify many disks to add
public static IWithManagedDataDisk WithExistingDataDisks(this IWithManagedDataDisk self, params IDisk[] disks)
{
return self.WithExistingDataDisks((IEnumerable<IDisk>) disks);
}
// allow to add an enumerable of many disks
public static IWithManagedDataDisk WithExistingDataDisks(this IWithManagedDataDisk self, IEnumerable<IDisk> disks)
{
foreach (var disk in disks)
self = self.WithExistingDataDisk(disk);
return self;
}
}
and use it like that:
var tempVM = await azure.VirtualMachines.Define(targetVMName)
.WithRegion(vm.Region)
.WithExistingResourceGroup(targetResourceGroupName)
.WithNewPrimaryNetworkInterface(nicDefinitions[0])
.WithSpecializedOSDisk(disks[0], disks[0].OSType.Value)
.WithSize(vm.Size)
.WithTags(tags)
.WithExistingDataDisks(d[0], d[1], d[2], d[3])
//.WithExistingDataDisks(d)
.CreateAsync();
Upvotes: 1