how to pass Func<AsyncExpiringLazy<AccessTokenResponse>> _tokenRespons; to constructor and initialize value - webjob

ILogger<ResilientStreamingClient> _logger;
IOptions<SalesforceConfiguration> _options;
Func<AsyncExpiringLazy<AccessTokenResponse>> _tokenRespons;
var StreamingClient = new ResilientStreamingClient(_tokenRespons, _options, _logger);

Related

DbContext state and global query filters

I've defined a global query filter in my OnModelCreating as follows:
modelBuilder.Entity<MyEntity>().HasQueryFilter(e => e.UserId == _currentUser || _currentUserIsAdmin);
And added the following method to my DbContext:
private int? _currentUser;
private bool _currentUserIsAdmin;
public void SetCurrentUser (int? currentUser)
{
_currentUser = currentUser;
_currentUserIsAdmin = Users.Find(currentUser)?.Role == "Admin";
}
However, I realized that when resolving my DbContext from the container it always resolves the very same instance. That means that two concurrent API calls would both call SetCurrentUser and overwrite it for the other API call - oops.
How to perform this properly?
My DI code looks like this:
var services = new ServiceCollection();
services.AddDbContext<MyDbContext>(options => options.UseSqlServer(connectionString));
using var serviceProvider = services.BuildServiceProvider();
[...]
var dbContext = serviceProvider.GetRequiredService<MyDbContext>();

How to pass a parameter to a Mobx Controller (Flutter)

I am an Android Developer and new to Flutter. I really like the way Mobx works, because it remembers me Android's ViewModel. By the way, when I create a ViewModel, I like to create it passing the repository as a parameter, so I can test it with different Data Sources (ie. local or cloud).
So, this is my class right now.
import 'package:mobx/mobx.dart';
part 'create_bill_controller.g.dart';
class CreateBillController = _CreateBillControllerBase
with _$CreateBillController;
abstract class _CreateBillControllerBase with Store {
final appBarTitle = 'Criar Conta';
final criarConta = 'Criar conta';
final nomeDaConta = 'Nome da conta';
final seuNome = 'Seu nome';
#action
createBill(String billname, String userName) {
// here, dataSource should be given in a constructor
datasource.createBill(billName, userName);
}
}
How can I pass a DataSource (repository) as a parameter to this class?
What you need is to declare constructor for CreateBillController instead of _CreateBillControllerBase, because constructor is not inherited by child class in Dart. The simplest way is to assign the passed in datasource to the corresponding property in parent class in the constructor, as you can see in the below snippet. You can also implement a constructor for _CreateBillControllerBase as well and call super(datasource) in CreateBillController's constructor.
import 'package:mobx/mobx.dart';
part 'create_bill_controller.g.dart';
class CreateBillController extends _CreateBillControllerBase with _$CreateBillController {
// HERE! Implement constructor for CreateBillController
// Do this if you have a constructor for _CreateBillControllerBase
//
// CreateBillController(DataSource datasource) : super(datasource)
//
CreateBillController(DataSource datasource) {
super.datasource = datasource;
}
}
abstract class _CreateBillControllerBase with Store {
final appBarTitle = 'Criar Conta';
final criarConta = 'Criar conta';
final nomeDaConta = 'Nome da conta';
final seuNome = 'Seu nome';
// HERE! Declare datasource
DataSource datasource;
#action
createBill(String billname, String userName) {
datasource.createBill(billName, userName);
}
}

Custom EF Core AddOrUpdate with composite keys

I've built an extension for Microsoft.EntityFrameworkCore that implements the AddOrUpdateMethod. It's working fine, but with entities with a composite primary key the AnyAsync method return always false, even if there are objects with the same key.
This is the method:
public static async Task AddOrUpdateAsync<TEntity>(this DbSet<TEntity> table, Expression<Func<TEntity, object>> key, Expression<Func<TEntity, bool>> deleteExpression, params TEntity[] entities) where TEntity : class
{
var getKeyFunction = key.Compile();
var getShouldDeleteFunction = deleteExpression.Compile();
var context = GetDbContext(table);
foreach (var entity in entities)
{
var primaryKey = getKeyFunction(entity);
var body = Expression.Equal(Expression.Convert(key.Body, primaryKey.GetType()), Expression.Constant(primaryKey));
Expression<Func<TEntity, bool>> query = Expression.Lambda<Func<TEntity, bool>>(body, key.Parameters);
var exist = await table.AnyAsync(query);
context.Entry(entity).State = exist
? getShouldDeleteFunction(entity) ? EntityState.Deleted : EntityState.Modified
: getShouldDeleteFunction(entity) ? EntityState.Detached : EntityState.Added;
}
}
private static DbContext GetDbContext<T>(this DbSet<T> table) where T : class
{
var infrastructure = table as IInfrastructure<IServiceProvider>;
var serviceProvider = infrastructure.Instance;
var currentDbContext = serviceProvider.GetService(typeof(ICurrentDbContext)) as ICurrentDbContext;
return currentDbContext.Context;
}
and I'm using it like this:
await db.Reports.AddOrUpdateAsync(r => new { r.Number, r.Year }, r => r.Active == false, response.Reports.ToArray());
I think that's happening because I'm using an anonymous type as the key, but I've no idea how to fix this.
The problem seems to be the usage of the anonymous type constant expression, which currently is causing client evaluation, and C# operator == compares anonymous types by reference, hence always returns false.
The trick to get the desired server translation is to "invoke" the key expression with entity by replacing the parameter with Expression.Constant(entity) (Expression.Invoke doesn't work in this case)
So remove the line var getKeyFunction = key.Compile(); as no longer needed, and use the following:
foreach (var entity in entities)
{
var parameter = key.Parameters[0];
var body = Expression.Equal(
key.Body,
key.Body.ReplaceParameter(parameter, Expression.Constant(entity))
);
var query = Expression.Lambda<Func<TEntity, bool>>(body, parameter);
var exist = await table.AnyAsync(query);
// ...
}
where ReplaceParameter is the usual expression helper method:
public static partial class ExpressionUtils
{
public static Expression ReplaceParameter(this Expression expression, ParameterExpression source, Expression target)
=> new ParameterReplacer { Source = source, Target = target }.Visit(expression);
class ParameterReplacer : ExpressionVisitor
{
public ParameterExpression Source;
public Expression Target;
protected override Expression VisitParameter(ParameterExpression node)
=> node == Source ? Target : node;
}
}

Create a BindableProperty depending on multiple properties

I'm trying to bind a UI element to different model properties A, B and AB. The first two properties A and B are controlled by two sliders. The third property AB is the sum of A and B. For each of the three properties there is a label displaying its value.
Now if I move one of the sliders, the corresponding label updates its Text. But the label for the combined property AB is not updated. Probably no "property changed" event is fired, since there is no setter for AB.
Is there any possibility for binding to such an "aggregated" property?
Here is the bindable object containing the properties A, B and AB:
public class Settings: BindableObject
{
public static readonly BindableProperty AProperty = BindableProperty.Create<Settings, double>(p => p.A, 0);
public static readonly BindableProperty BProperty = BindableProperty.Create<Settings, double>(p => p.B, 0);
public static readonly BindableProperty ABProperty = BindableProperty.Create<Settings, double>(p => p.AB, 0);
public double A {
get{ return (double)GetValue(AProperty); }
set{ SetValue(AProperty, (double)value); }
}
public double B {
get{ return (double)GetValue(BProperty); }
set{ SetValue(BProperty, (double)value); }
}
public double AB {
get{ return A + B; }
}
}
And here is the page containing both sliders and the three labels:
public class App : Application
{
public App()
{
var settings = new Settings();
var sliderA = new Slider();
sliderA.ValueChanged += (sender, e) => settings.A = e.NewValue;
var sliderB = new Slider();
sliderB.ValueChanged += (sender, e) => settings.B = e.NewValue;
var labelA = new Label{ BindingContext = settings };
labelA.SetBinding(Label.TextProperty, "A");
var labelB = new Label{ BindingContext = settings };
labelB.SetBinding(Label.TextProperty, "B");
var labelAB = new Label{ BindingContext = settings };
labelAB.SetBinding(Label.TextProperty, "AB");
MainPage = new ContentPage {
Content = new StackLayout {
VerticalOptions = LayoutOptions.Center,
Children = { sliderA, sliderB, labelA, labelB, labelAB },
},
};
}
}
This is what the running application looks like on iOS:
The last label should display the sum of the first two numbers.
Edit:
I wonder why I can't write
public static readonly BindableProperty ABProperty =
BindableProperty.Create<Settings, double>(p => p.A + p.B, 0);
But this yields the run-time error "System.TypeInitializationException: An exception was thrown by the type initializer for AggregatedBindablePropertyMnml.Settings ---> System.Exception: getter must be a MemberExpression"
Based on the suggestion from Taekahn (updating AB within the setters of A and B) I came up with the following solution.
By overriding the OnPropertyChanged method and setting the ABProperty, the bound label text is updated as well. In contrast to modifying each setter individually, this way we only need to modify the Settings class at one place.
protected override void OnPropertyChanged(string propertyName = null)
{
base.OnPropertyChanged(propertyName);
SetValue(ABProperty, A + B);
}
Now both sliders impact the third label:

How to create custom model binder for Mongodb ObjectId in Nancy?

In asp.net mvc I did it like this.
public class ObjectIdBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var result = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
return new ObjectId(result.AttemptedValue);
}
}
How would I do that in Nancy?
Also how do you register it in bootstrapper? code sample?
So I ended up creating an extension to Nancy's Request class.
I created a new Body method that takes a type and uses Json.Net contract to
bind any property in the model that is type ObjectId.
public static class BodyBinderExtension
{
public static T Body<T>(this Request request)
{
request.Body.Position = 0;
string bodyText;
using (var bodyReader = new StreamReader(request.Body))
{
bodyText = bodyReader.ReadToEnd();
}
JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
ContractResolver = new ObjectIDContractResolver()
};
return JsonConvert.DeserializeObject<T>(bodyText);
}
}