Composing a Polly Policy with user feedback - c#

There are several policy's that need to be the same throughout my code. For example:
var myIOProblems = Policy
.Handle<IOException>()
.WaitAndRetryForever(i => TimeSpan.FromSeconds(2));
Then I'll have some code that will do the work:
myIOProblems
.Execute(() => otherPath.CopyTo(otherPathPart.FullName));
This works great, and I can litter the latter statements all over my code, change the behavior in one central place, and it all seems to work.
But in some places I need to provide the user/framework some feedback that problems are occurring. I can write a new policy:
Policy
.Handle<IOException>()
.WaitAndRetryForever(i => TimeSpan.FromSeconds(2), (e, t, c) =>
{
count++;
statusUpdate.PCall($"Copying {otherPath.Name}: {other.Name} -> {Name} (retry ({count}): {e.Message})");
})
.Execute(() => otherPath.CopyTo(otherPathPart.FullName));
But now I've lost the ability to re-use common code. What I'd really like to be able to write is something like the following:
myIOProblems
.OnRetry(e => statusUpdate.PCall($"Error ({e.Message}), retrying"))
.Execute(() => otherPath.CopyTo(otherPathPart.FullName));
Or something similar to that. I may be overlooking something in the library, in which case I apologize!

You can wrap your policy in a factory class and the getter function will optionally receive the onRetry callback:
public class PolicyFactory
{
public static Policy GetMyPolicy(Action<Exception, TimeSpan, Context> onRetry = null)
{
return Policy
.Handle<IOException>()
.WaitAndRetryForever(i => TimeSpan.FromSeconds(2), onRetry);
}
}

Related

What is the functionality of IncrementalValuesProvider.WithTrackingName(string name)?

In the context of a .net6 incremental source generator, what does the IncrementalValuesProvider.WithTrackingName(string name) method do?
In addition how/when is it intended to be used?
[Generator]
public class MyGenerator : IIncrementalGenerator
{
var incremntalValueProvider = context.SyntaxProvider
.CreateSyntaxProvider(predicate: (n, c) => { ... }, transform: (s, c) => { ... });
incremntalValueProvider = incremntalValueProvider.WithTrackingName("Some tracking name");
}
With most things when it comes to source generators, I have been able to google and use a bit of trial and error, to figure out how things work.
However with this particular method, those aproaches has not been helpful. In addition it seems like Micrsofts documentation is pretty much out of date since
https://github.com/dotnet/roslyn/blob/main/docs/features/incremental-generators.md does not even mention the method.

ASP .NET Core Authorization Handler: Get single failing requirement

Assuming a policy SomePolicy contains list of IAuthorizationRequirement added as such:
services.AddAuthorization(options =>
{
options.AddPolicy("SomePolicy", policy =>
{
policy.AddRequirements(new FooRequirement());
policy.AddRequirements(new BarRequirement());
policy.AddRequirements(new YetAnotherRequirement());
});
});
Upon execution of the policy, I would like to know which of the requirement failed and prevent the check of the remaining requirements.
Looking up what I can do with the API, it appears that after execution of the policy, the only thing I can do is retrieve the list of failed requirements.
var authorizationResult = _authorizationService.AuthorizeAsync(this.User, ressource, "SomePolicy");
var failedRequirements = authorizationResult.Result.Failure.FailedRequirements
Is a policy based approach not suited for what I am trying to achieve ?
Should I create dedicated policy for each of the requirement ?
Any help would be much appreciated, thanks !
Each requirement needs to have context.Succeed(requirement) called by one of the handlers, and no context.Failed() calls by any handler.
InvokeHandlersAfterFailure is a way to short-circuit handler invocations for a particular requirement once context.Failed() has been called, but that isn't very useful IMO.
I'm trying to get short-circuit evaluation by adding an extension method to IAuthorizationService:
public static async Task<AuthorizationResult> AuthorizeAnyAsync(this IAuthorizationService service, ClaimsPrincipal user,
object? resource, params IAuthorizationRequirement[] requirements)
{
AuthorizationResult? result = null;
foreach (var requirement in requirements)
{
result = await service.AuthorizeAsync(user, resource, requirement);
if (result.Succeeded || result.Failure.FailCalled)
return result;
}
return result!;
}

How to chain constructors in Structuremap?

Is there a way to chain the constructors in Structuremap? I would want a more succinct code - basically trying to get rid of the new keyword in codebase.
Currently what I have:
container.Configure(c =>
{
c.For<IDataContext>()
.Singleton()
.Use(new CarDataContextWrapper(new CarDataContext(Settings.Default.ConnectionString)
{
CommandTimeout = 60
}));
});
To inject in the constructor parameters, I would want to using .Ctor declaration. But how would I do it for the second class that I want to initialize?
container.Configure(c =>
{
c.For<IDataContext>()
.Use<CarDataContextWrapper>()
.Ctor<CarDataContext>().Is(x=>); // HOW TO SET THIS?
});
container.Configure(c =>
{
c.For<IDataContext>()
.Use<CarDataContextWrapper>("getting context", ctx=>
{
return ctx.GetInstance<CarDataContextWrapper>();
});
// Also need to tell SM how to build CarDataContextWrapper
});

Is it possible to mock the "type name" of a mock in C# using Moq?

I'm developing a chatbot in C# (based on .NET Core) that has modular behaviours. One of the behaviours I want to develop is an "admin" module that (among other functions) should allow admins to dynamically enable or disable other behaviours by name.
I want the admin module to determine the name of a behaviour by inspecting its type info and doing something like:
var name = behaviour.GetType().GetTypeInfo().Name.Replace("Behaviour", string.Empty).ToLowerInvariant();
In a BDD specification I'm writing first, I'm trying to set up a "behaviour chain" consisting of the admin module (system under test) and a mock behaviour. The tests involve sending commands that should cause the admin module to enable or disable the mock behaviour.
This is what I've done so far:
public BehaviourIsEnabled() : base("Admin requests that a behaviour is enabled")
{
var mockTypeInfo = new Mock<TypeInfo>();
mockTypeInfo.SetupGet(it => it.Name).Returns("MockBehaviour");
var mockType = new Mock<Type>();
mockType.Setup(it => it.GetTypeInfo()).Returns(mockTypeInfo.Object);
// TODO: make mock behaviour respond to "foo"
var mockBehaviour = new Mock<IMofichanBehaviour>();
mockBehaviour.Setup(b => b.GetType()).Returns(mockType.Object);
this.Given(s => s.Given_Mofichan_is_configured_with_behaviour("administration"), AddBehaviourTemplate)
.Given(s => s.Given_Mofichan_is_configured_with_behaviour(mockBehaviour.Object),
"Given Mofichan is configured with a mock behaviour")
.And(s => s.Given_Mofichan_is_running())
.When(s => s.When_I_request_that_a_behaviour_is_enabled("mock"))
.And(s => s.When_Mofichan_receives_a_message(this.JohnSmithUser, "foo"))
.Then(s => s.Then_the_mock_behaviour_should_have_been_triggered())
.TearDownWith(s => s.TearDown());
}
The problem when I run this is that GetTypeInfo() is an extension method on Type, so Moq throws the exception:
Expression references a method that does not belong to the mocked
object: it => it.GetTypeInfo()
An an alternative, I could just add a Name property to IMofichanBehaviour, but I don't like the idea of adding arbitrary methods/properties to production code that's only really there for the benefit of test code.
Keep it simple with a fake class that satisfies what it being mocked.
public class MockBehaviour : IMofichanBehaviour { ... }
And test would then look like
public BehaviourIsEnabled() : base("Admin requests that a behaviour is enabled") {
// TODO: make mock behaviour respond to "foo"
var mockBehaviour = new MockBehaviour();
this.Given(s => s.Given_Mofichan_is_configured_with_behaviour("administration"), AddBehaviourTemplate)
.Given(s => s.Given_Mofichan_is_configured_with_behaviour(mockBehaviour),
"Given Mofichan is configured with a mock behaviour")
.And(s => s.Given_Mofichan_is_running())
.When(s => s.When_I_request_that_a_behaviour_is_enabled("mock"))
.And(s => s.When_Mofichan_receives_a_message(this.JohnSmithUser, "foo"))
.Then(s => s.Then_the_mock_behaviour_should_have_been_triggered())
.TearDownWith(s => s.TearDown());
}

'Flushing' observable Scan

This is a weird 'problem', I'm not sure what the best way to handle it is.
To simplify, let's say that I've got an observable source with some data reading coming from 'outside':
{ Value, TimeStamp }
I'm putting that through Observable.Scan so that I can output:
{ Value, TimeStamp, TimeDelta }
This means that my data always comes out 'one late', but that's not a problem.
We're 'recording' from this observable, and when you stop one recording, there's still one data value 'stuck' waiting for it's follower.
Even that's not a problem. The problem is that when you go to start recording again, the last value from the previous 'recording' gets stuck on to the beginning of the new one.
The most obvious thing to do is just to unsubscribe and resubscribe, but.... it's not that simple, because this scanned source is not only recorded, but also sent to the UI, and used for further calculations down the line: so I'd have to do an enormous unsubscribe/resubscribe.
I'm trying to think of a way to inject some kind of 'reset' data, but not sure how one goes about sending information back 'up' the observable stream...
Maybe I've just bitten off more than I can chew? Or used too much Observable?
There are going to be a number of ways to do this, but one that is fairly easy is to use the .Switch() operator.
It essentially works like this: if you have an IObservable<IObservable<T>> you can then call .Switch() to turn it into an IObservable<T> where it basically subscribes to the last value produced by the outer observable and unsubscribes to the previously produced observable.
Now that sounds a bit funky, but here's how it can work. Given you have an observable called outsideObservable then you defining a second observable (resubscribeObservable) that produces a value every time you want to resubscribe, and you subscribe to them like this:
var subscription =
resubscribeObservable
.Select(_ => outsideObservable)
.Switch()
.Subscribe(x =>
{
/* Do stuff here */
});
Now to resubscribe to outsideObservable you just have to produce a value from resubscribeObservable.
The easiest way to do this is to define it like var resubscribeObservable = new Subject<Unit>(); and then call resubscribeObservable.OnNext(Unit.Default); every time you want to resubscribe.
Alternatively if you have some event, say a user clicking a button, then you could use an observable based on that event as your resubscribeObservable.
Integrating suggestions from the comments, this would look something like:
var factory = Observable.Defer(() => outsideObservable);
var resetterObservable = new Subject<Unit>();
var resettableObservable =
resetterObservable
.StartWith(Unit.Default)
.Select(_ => factory)
.Switch()
.Publish()
.RefCount();
The Publish().RefCount() is just to protect the outsideObservable from multiple simultaneous subscriptions.
This is what I've boiled the accepted answer down to. Not yet in production, but tests seem to show it does what I want.
public interface IResetter
{
IObservable<T> MakeResettable<T>(Func<IObservable<T>> selector);
}
public class Resetter : IResetter
{
private Subject<Unit> _Resetter = new Subject<Unit>();
public void Reset()
{
_Resetter.OnNext(Unit.Default);
}
public IObservable<T> MakeResettable<T>(Func<IObservable<T>> selector)
{
return
_Resetter
.StartWith(Unit.Default)
.Select(_ => Observable.Defer(selector))
.Switch()
.Publish().RefCount();
}
}

Categories

Resources