Xamarin iOS Webkit: How do I resolve NIDActionArity1V59? - ios

I need to override the following DecidePolicy() in a subclass but I get build errors because the compiler isn't able to resolve NIDActionArity1V59. Where is NIDActionArity1V59 implemented so I can apply the required using statement,
using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using Foundation;
using ObjCRuntime;
namespace WebKit
{
//
// Summary:
// Delegate object for WebKit.WKNavigation objects, provides methods relating to
// navigation and load policies.
[Introduced(PlatformName.MacOSX, 10, 10, PlatformArchitecture.Arch64, null)]
[Introduced(PlatformName.iOS, 8, 0, PlatformArchitecture.None, null)]
[Model]
[Protocol]
[Register("WKNavigationDelegate", false)]
public class WKNavigationDelegate : NSObject, IWKNavigationDelegate, INativeObject, IDisposable
{
[...]
//
// Summary:
// Assigns an action to be taken after the specified navigationAction has been either
// canceled or allowed.
[CompilerGenerated]
[Export("webView:decidePolicyForNavigationAction:decisionHandler:")]
public virtual void DecidePolicy(WKWebView webView, WKNavigationAction navigationAction, [BlockProxy(typeof(NIDActionArity1V59))] Action<WKNavigationActionPolicy> decisionHandler);
[...]
}
}

Why do you need this attribute? You can simply override it like
public class MyNavigationDelegate : WKNavigationDelegate
{
public override void DecidePolicy(WKWebView webView, WKNavigationAction navigationAction, Action<WKNavigationActionPolicy> decisionHandler)
{
// do some stuff
}
}
The BlockProxy attribute is only used internally as far as I know. https://developer.xamarin.com/api/type/ObjCRuntime.BlockProxyAttribute/
And if you have a look at the documentation you will not see a single attribute, because they aren't part of the signature of a function. So I guess, you confused yourself a bit by looking too deep in the decompiled sources ;)
Tip:
When you type override followed by a space, Visual Studio offers you the correct overloads. So you have not to search for them.

Related

How to access a DurableEntityClient in an injected class with Azure Durable Functions

I have an Azure Functions project that leverages Dependency Injection (Startup.cs injects services based on the different interfaces). Those services that implement the interfaces are using constructor dependency injection as well.
In one of those implementations, I want to call a method on a Durable Entity, but I prefer not to make the DurableEntityClient part of the method signature (as other implementations might not need the EntityClient at all). So therefore, I was hoping to see that IDurableEntityClient injected in the constructor of my class.
But it turns out the value is null. Wondering if this is something that is supported and feasible? (to have a DI-friendly way of injecting classes that want to get the EntityClient for the Functions runtime they are running in)
Some code snippets:
Startup.cs
builder.Services.AddSingleton<IReceiver, TableReceiver>();
Actual Function
public class ItemWatchHttpTrigger
{
private IReceiver _receiver;
public ItemWatchHttpTrigger(IReceiver receiver)
{
_receiver = receiver;
}
[FunctionName("item-watcher")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", Route = "item/{itemId}")]
HttpRequest request, string itemId, [DurableClient] IDurableEntityClient client, ILogger logger)
{
// Actual implementation
}
}
Referenced class
public class TableReceiver : IReceiver
{
private IDurableEntityClient _entityClient;
public TableReceiver(IDurableEntityClient client)
{
_entityClient = client; // client is null :(
}
}
Based on the answer of my github issue, it seems it is possible to inject this in Startup, since the 2.4.0 version of the Microsoft.Azure.WebJobs.Extensions.DurableTask package:
Some code snippets:
Startup.cs
builder.Services.AddSingleton<IReceiver, TableReceiver>();
builder.Services.AddDurableClientFactory();
Referenced class
public class TableReceiver : IReceiver
{
private IDurableEntityClient _entityClient;
public TableReceiver(IDurableClientFactory entityClientFactory, IConfiguration configuration)
{
_entityClient = entityClientFactory.CreateClient(new DurableClientOptions
{
TaskHub = configuration["TaskHubName"]
});
}
}
Github issue

IDisposable implementation when container is guaranteed to call Dispose method

I have built a API service using ASP.NET Core. Just like any other API, this one has to retrieve some data from database, apply some business logic and then send data back to the client.
To start with, I have EmployeeDataContext class that is scaffolded using Entity Framework.Core. This class is derived from Microsoft.EntityFrameworkCore.DbContext as shown below.
public partial class EmployeeDataContext : DataContext
{
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
......
}
}
This data context class is used in a data provider class as follows.
public class EmployeeDataProvider : IEmployeeDataProvider, IDisposable
{
private EmployeeDataContext dataContext;
public EmployeeDataProvider(EmployeeDataContext context)
{
this.dataContext = context;
}
// Various CRUD methods
// Dispose
public void Dispose()
{
if ( this.dataContext != null )
{
this.dataContext.Dispose();
}
}
}
The service layer holds a reference to data provider as follows.
public class EmployeeService : IEmployeeService
{
private IEmployeeDataProvider dataProvider;
public EmployeeService(IEmployeeDataProvider dataProvider)
{
DataProvider = dataProvider;
}
// Add/Delete/Update Employee related calls
}
All the dependencies are injected in Startup class as follows.
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IEmployeeDataProvider, EmployeeDataProvider>();
services.AddScoped<IEmployeeService, EmployeeService>();
}
}
According to Microsoft doc
The container will call Dispose for IDisposable types it creates.
This mean that EmployeeDataProvider.Dispose() method will be called by container at the end of request lifecycle.
The question I have is about how to implement IDisposable for EmployeeDataProvider class. The link provides best practices for implementing IDisposable for various scenarios which may require you to implement Disposable(bool) also. However, for this scenario, I am not sure if
all that is needed and my current (simple) implementation of Dispose is good enough because (since there is no call via finalizer is involved here). Is my understanding and IDisposable look correct for this situation?
Implementing IDisposable is trivial in the case where your class is sealed:
public sealed class Foo : IDisposable {
private readonly FileStream stream;
public Foo() {
this.stream = new FileStream( ... );
}
public void Dispose() {
this.stream.Dispose();
}
}
You only need the protected virtual void Dispose(Boolean disposing) method, and the recommended implementation of IDisposable if your class will be subclassed.
This is described in the documentation for FxCop rule CA1063 "Implement IDisposable correctly": https://msdn.microsoft.com/en-us/library/ms244737.aspx
Dispose() is not public, sealed, or named Dispose.
Dispose(bool) is not protected, virtual, or unsealed.
In unsealed types, Dispose() must call Dispose(true).
For unsealed types, the Finalize implementation does not call either or both Dispose(bool) or the case class finalizer.
[...]
How to Fix Violations
[...]
Ensure that $className is declared as public and sealed.
Another tip: if your fields are only ever assigned in the type initializer or in the constructor - and should never be assigned a null value - then you should use the readonly modifier (or use read-only auto-properties - which have a readonly backing field) and that way you don't need to do a null-check in your Dispose method.
Note that Dispose() methods are generally idempotent:
https://msdn.microsoft.com/en-us/library/fs2xkftw.aspx
To help ensure that resources are always cleaned up appropriately, a Dispose method should be callable multiple times without throwing an exception.
Historically there were a few classes in .NET 1.x and 2.x that did throw ObjectDisposesException if they were Disposed twice, but I haven't personally observed non-idempotent behaviour since upgrading to .NET 4.x - though it's possible that some poorly-written third-party libraries and components might implement it incorrectly, however.

Call WebView page method from referenced WinRT Component with AllowForWeb class

I have a XAML page with WebView inside (for example MainPage.xaml). Also I have WinRT Component with class marked with [AllowForWeb] attribute. This component is referenced from project where MainPage.xaml located and in code-behind AddWebAllowedObject method is used. And I can't reference main project back because of circular dependency.
How to call MainPage.xaml.cs methods from component class? Very usual situation. Is there are some standard way to do it?
For example. I have a method inside RT component that could be called from JavaScript
public void ShowMessage(string message)
{
// I want to call here function from MainPage.xaml.cs
}
How to call MainPage.xaml.cs methods from component class? Very usual situation. Is there are some standard way to do it?
Yes, you can pass the method from MainPage.xaml.cs to Windows Runtime Component through delegate(Currently it's very limited to use delegate in Runtime Component using C#, see this case, so I use C++ as demo).
For Runtime Component Class MyClass.h:
public delegate Platform::String^ MyFunc(int a, int b);
public ref class MyClass sealed
{
public:
MyClass();
static Platform::String^ MyMethod(MyFunc^ func)
{
Platform::String^ abc=func(4, 5);
return abc;
}
};
And you can use the delegate in code behind like below:
using MyComponentCpp;
private void myBtn_Click(object sender, RoutedEventArgs e)
{
String abc=MyClass.MyMethod(MyMethod);
myTb.Text = abc;
}
private String MyMethod(int a, int b)
{
return (a.ToString() + b.ToString());//replace this line with your own logic.
}
And here is the complete Demo: TestProject.
Thankfully to #Elvis Xia who has gived me idea, I has found a solution how to do it without C++.
I have create a third project as Class Library. It doesn't has restrictions to use Action. This library I have referenced from main project and from WinRT component. Code of class inside library:
public class BridgeClass
{
public static event Action<string> MessageReceived;
public static void Broadcast(string message)
{
if (MessageReceived != null) MessageReceived(message);
}
}
Code inside main project with webview is:
// place somewhere
BridgeClass.MessageReceived += ShowMessage;
// ....... and add a method
void ShowMessage(string msg)
{
}
And now i can call this code from WinRT component:
public void ShowMessage(string message)
{
BridgeClass.Broadcast("lalala");
}

F# Public Override of Protected Methods

I've just started learning F# and I'm using it with Monogame to create a simple game to help myself learn the various features of the language. I've hit a roadblock trying to access my game class from outside because the Monogame Game class defines the methods as protected. Trying to do a public override of the method throws an error, telling me setting an accessibility modifiers are not permitted.
Base Class Defined in C#
public class Base
{
protected virtual void Method()
{
//...
}
}
Public Override in F#
type Game as game =
inherit Base()
//Error: Accessibility modifiers are not permitted on overrides or interface implementations
override public game.Method =
//...
()
Q: What is the correct way to do a public F# override of an inherited protected C# method?
Changing accessibility on overrides is not allowed, in either F# or C#. Based on #Endjru's, the best approach is to use a wrapper method that is public to call the protected method;
type Game as game =
inherit Base()
override game.Method =
//...
()
member game.PublicMethod = game.Method

Ninject selecting parameterless constructor when using implicit self-binding

I am using Ninject version 3 in an MVVM-type scenario in a .NET WPF application. In a particular instance I am using a class to act as coordinator between the view and its view model, meaning the coordinator class is created first and the view and view model (along with other needed services) are injected into it.
I have bindings for the services, but I have not created explicit bindings for the view/view model classes, instead relying on Ninject's implicit self-binding since these are concrete types and not interfaces.
A conceptual version of this scenario in a console app is shown below:
class Program
{
static void Main(string[] args)
{
StandardKernel kernel = new StandardKernel();
kernel.Bind<IViewService>().To<ViewService>();
//kernel.Bind<View>().ToSelf();
//kernel.Bind<ViewModel>().ToSelf();
ViewCoordinator viewCoordinator = kernel.Get<ViewCoordinator>();
}
}
public class View
{
}
public class ViewModel
{
}
public interface IViewService
{
}
public class ViewService : IViewService
{
}
public class ViewCoordinator
{
public ViewCoordinator()
{
}
public ViewCoordinator(View view, ViewModel viewModel, IViewService viewService)
{
}
}
If you run this code as-is, the kernel.Get<> call will instantiate the ViewCoordinator class using the parameterless constructor instead of the one with the dependencies. However, if you remove the parameterless constructor, Ninject will successfully instantiate the class with the other constructor. This is surprising since Ninject will typically use the constructor with the most arguments that it can satisfy.
Clearly it can satisfy them all thanks to implicit self-binding. But if it doesn't have an explicit binding for one of the arguments it seems to first look for alternate constructors it can use before checking to see if it can use implicit self-binding. If you uncomment the explicit Bind<>().ToSelf() lines, the ViewController class will instantiate correctly even if the parameterless constructor is present.
I don't really want to have to add explicit self-bindings for all the views and view models that may need this (even though I know that burden can be lessened by using convention-based registration). Is this behavior by design? Is there any way to tell Ninject to check for implicit self-binding before checking for other usable constructors?
UPDATE
Based on cvbarros' answer I was able to get this to work by doing my own implementation of IConstructorScorer. Here's the changes I made to the existing code to get it to work:
using Ninject.Selection.Heuristics;
class Program
{
static void Main(string[] args)
{
StandardKernel kernel = new StandardKernel();
kernel.Components.RemoveAll<IConstructorScorer>();
kernel.Components.Add<IConstructorScorer, MyConstructorScorer>();
kernel.Bind<IViewService>().To<ViewService>();
ViewCoordinator viewCoordinator = kernel.Get<ViewCoordinator>();
}
}
using System.Collections;
using System.Linq;
using Ninject.Activation;
using Ninject.Planning.Targets;
using Ninject.Selection.Heuristics;
public class MyConstructorScorer : StandardConstructorScorer
{
protected override bool BindingExists(IContext context, ITarget target)
{
bool bindingExists = base.BindingExists(context, target);
if (!(bindingExists))
{
Type targetType = this.GetTargetType(target);
bindingExists = (
!targetType.IsInterface
&& !targetType.IsAbstract
&& !targetType.IsValueType
&& targetType != typeof(string)
&& !targetType.ContainsGenericParameters
);
}
return bindingExists;
}
private Type GetTargetType(ITarget target)
{
var targetType = target.Type;
if (targetType.IsArray)
{
targetType = targetType.GetElementType();
}
if (targetType.IsGenericType && targetType.GetInterfaces().Any(type => type == typeof(IEnumerable)))
{
targetType = targetType.GetGenericArguments()[0];
}
return targetType;
}
}
The new scorer just sees if a BindingExists call failed by overriding the BindingExists method and if so it checks to see if the type is implicitly self-bindable. If it is, it returns true which indicates to Ninject that there is a valid binding for that type.
The code making this check is copied from the SelfBindingResolver class in the Ninject source code. The GetTargetType code had to be copied from the StandardConstructorScorer since it's declared there as private instead of protected.
My application is now working correctly and so far I haven't seen any negative side effects from making this change. Although if anyone knows of any problems this could cause I would welcome further input.
By default, Ninject will use the constructor with most bindings available if and only if those bindings are defined (in your case they are implicit). Self-bindable types do not weight when selecting which constructor to use.
You can mark which constructor you want to use by applying the [Inject] attribute to it, this will ensure that constructor is selected.
If you don't want that, you can examine StandardConstructorScorer to see if that will fit your needs. If not, you can replace the IConstructorScorer component of the Kernel with your own implementation.

Resources