rspec/rules/S6424/csharp/rule.adoc

91 lines
3.1 KiB
Plaintext
Raw Normal View History

== Why is this an issue?
The recommended way to access Azure Durable Entities is Interfaces via generated proxy objects.
The following restrictions, during interface design, are enforced:
* Entity interfaces must be defined in the same assembly as the entity class. This is not detected by the rule.
* Entity interfaces must only define methods.
* Entity interfaces must not contain generic parameters.
* Entity interface methods must not have more than one parameter.
* Entity interface methods must return void, Task, or Task<T>.
If any of these rules are violated, an `InvalidOperationException` is thrown at runtime when the interface is used as a type argument to `IDurableEntityContext.SignalEntity<TEntityInterface>`, `IDurableEntityClient.SignalEntityAsync<TEntityInterface>` or `IDurableOrchestrationContext.CreateEntityProxy<TEntityInterface>`. The exception message explains which rule was broken.
This rule raises an issue in case any of the restrictions above is not respected.
=== Noncompliant code example
[source,csharp]
----
namespace Foo // Noncompliant, must be defined in the same assembly as the entity class that implements it
{
public interface ICounter<T> // Noncompliant, interfaces cannot contain generic parameters
{
string Name { get; set; } // Noncompliant, interface must only define methods
void Add(int amount, int secondParameter); // Noncompliant, methods must not have more than one parameter
int Get(); // Noncompliant, methods must return void, Task, or Task<T>
}
}
namespace Bar
{
public class Counter : ICounter
{
// do stuff
}
public static class AddToCounterFromQueue
{
[FunctionName("AddToCounterFromQueue")]
public static Task Run(
[QueueTrigger("durable-function-trigger")] string input,
[DurableClient] IDurableEntityClient client)
{
var entityId = new EntityId("Counter", "myCounter");
int amount = int.Parse(input);
return client.SignalEntityAsync<ICounter>(entityId, proxy => proxy.Add(amount, 10));
}
}
}
----
=== Compliant solution
[source,csharp]
----
namespace Bar
{
public interface ICounter
{
void Add(int amount);
Task<int> Get();
}
}
namespace Bar
{
public class Counter : ICounter
{
// do stuff
}
public static class AddToCounterFromQueue
{
[FunctionName("AddToCounterFromQueue")]
public static Task Run(
[QueueTrigger("durable-function-trigger")] string input,
[DurableClient] IDurableEntityClient client)
{
var entityId = new EntityId("Counter", "myCounter");
int amount = int.Parse(input);
return client.SignalEntityAsync<ICounter>(entityId, proxy => proxy.Add(amount));
}
}
}
----
== Resources
* https://docs.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-dotnet-entities#restrictions-on-entity-interfaces[Restrictions on Entity Interfaces]
* https://docs.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-entities?tabs=csharp[Durable Entities]