Xamarin XLabs IOC and camera - xamarin

I'm looking at https://github.com/XLabs/Xamarin-Forms-Labs/blob/master/Samples/XLabs.Sample/ViewModel/CameraViewModel.cs to try and get the camera available to my app.
I have this setup the same, but when I run my app the iOS app that calls my PCL is giving the error:
IResolver has not been set. Please set it by calling Resolver.SetResolver(resolver) method.
I don't know what this means or what exact code I need. I don't use IOC at all and I don't much care about it but I just want this camera to be available to my PCL. How can I get this camera available to my PCL when I'm not using MVC here.

If you wish to use the ViewModel then modify the constructor to take in IMediaPicker:
https://github.com/XLabs/Xamarin-Forms-Labs/blob/master/Samples/XLabs.Sample/ViewModel/CameraViewModel.cs#L62
public CameraViewModel(IMediaPicker mediaPicker)
{
this._mediaPicker = mediaPicker;
}
Remove the Setup function:
https://github.com/XLabs/Xamarin-Forms-Labs/blob/master/Samples/XLabs.Sample/ViewModel/CameraViewModel.cs#L156-L167
How you get the IMediaPicker implementation to PCL is up to you. IoC is the preferred (and easy) way but you can use other patterns as well. One would be to define a static Func<IMediaPicker> property on the ViewModel and set it in the platform specific projects.
IoC container is the easiest and quickest way to get it done and it would as simple as adding these lines at the application startup (e.g. AppDelegate's FinishedLaunching method):
var container = new SimpleContainer();
container.Register<IMediaPicker, MediaPicker>();
Resolver.SetResolver(container.GetResolver());

Related

Is there a simple way to auto register [Exports] in a Prism app? WPF .NET 4.8

I used to be on a project that used Prism and when we needed a new service to do something, we'd just create an interface, a concrete class that implemented that interface and exported it, and then it just became available everywhere for [ImportingConstructor]. We didn't need to manually register it or anything. I no longer have access to that project, but I don't think there was any reflection magic that was done manually to accomplish this.
I'm in a new company and we are starting up a project using MEF / Prism and I'm trying to accomplish the same thing, but as of right now, I'm having to manually register items in order to import them. What am I missing?
I'm in .NET 4.8 WPF app
Additional info
we are basing our project from this website
https://prismlibrary.com/index.html
This is our app class
public partial class App
{
protected override Window CreateShell()
{
return Container.Resolve<ShellWindow>();
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterSingleton<IStartupActionService, StartupActionService>();
containerRegistry.RegisterSingleton<IGeneralNavigationService, GeneralNavigationService>();
containerRegistry.RegisterSingleton<IExperimentSetupNavigationService, ExperimentSetupNavigationService>();
containerRegistry.RegisterSingleton<IProtocolSetupNavigationService, ProtocolSetupNavigationService>();
containerRegistry.RegisterSingleton<IOurProjectNavigationService, OurProjectNavigationService>();
containerRegistry.RegisterSingleton<IOurProjectUiService, OurProjectUiService>();
containerRegistry.RegisterManySingleton<WcfClientService>();
containerRegistry.RegisterSingleton<IControlClientService, ControlClientService>();
}
}
Why do I have to register each new service?
I've been reading about MEF, DryIoc, and others and I'm just not getting clear answers. Is there not a way to just have everything with an [Export] become immediately available for import?
Something else I need to do, that I think this whole registering thing is messing me up on is trying to come up with a way to have "dialogs" but tie them to a neutral class to make it more MVVM happy.
Dialog -> a region that pops open when you call a method. This method currently takes in a UserControl, assumed to have already been constructed and its ViewModel datacontext already attached.
What I would like to do and don't know how to start is
use a neutral container class to open one of these dialogs (similar to interaction request Notification
using attributes, attach an attribute to a view that indicates "I support this neutral container class" (assumed only one view per container)
this view supports [ImportingConstuctor] to bring in its ViewModel
the viewmodel itself supports [ImportingConstuctor] to bring in services needed
again, the desire to NOT need to register these items manually as we add them. Would like to add a service interface, the concrete class that [Export]s the interface and have it just available to the viewmodel and other services, and same for the views and viewmodels, export attribute tag them as necessary and have them just available to either/both grab an instance of them or manually create an instance of them and have their [ImportingConstructors] handled for me.

Xamarin Forms - calling a shared code method from the platform project

I have read the two other questions on SO regarding this and I wanted to know if there is a good solution for that now / best practice.
Long story short, we use an SDK which is written natively and we've wrapped it so that it works on Xamarin.Android and Xamarin.iOS. It has asynchronous callback methods. I need to call a method in the shared code when a callback is received in the Android project for instance.
There's a lot of info for doing the opposite - using DependencyService. How about in my scenario? Does anyone have experience with an app like this and what's the best approach to keep code clean and do this using MVVM?
The options I know are:
Using a static App instance - this is what we currently do.
MessagingCenter
Anything else?
Actually I've never seen anyone recommend usage of MessagingCenter for anything else than communication between ViewModels so I am not sure it is recommended here. Also, I need to know the sender object type so I need a reference to the class in the platform specific project.
I would recommend you to use messagingCenter to pass data or call method between shared project and platform project. You can just send a new object instead of the class in the platform specific project.
Also, have a look at using eventhandler as I mentioned in this answer may help someone who want to call from the shared project into the platform specific one.
BTW, I mean you can even pass an object as TSender if it is not necessary to use:
MessagingCenter.Send<Object>(new object(), "Hi");
MessagingCenter.Subscribe<Object>(new object(), "Hi", (sender) =>
{
// Do something whenever the "Hi" message is received
});

PushPopupPageAsync not found in Xamarin Forms Prism

Not found PushPopupPageAsync
_navigationService.PushPopupPageAsync( "MyPopupPage" );
I am using Rg.Plugin.Popup along withg Prism
but PushPopupPageAsync not available on INavigationService
how to solve it?
Are you sure that you should be calling PushPopupPageAsync? Rg.Plugin.Popup extends the Navigation service with PushPopupAsync - note there is no Page in the name.
To be able to use PushPopupAsync you also need to have:
using Rg.Plugins.Popup.Extensions;
in the source file where you want to call PushPopupAsync
Its easier to use the Prism.Plugin.Popups made by the Prism maintainer, then you can just use the standard NavigateAsync method:
_navigationService.NavigateAsync("MyPopupPage")
With this, te page is pushed as a popup with Rg.Plugin.Popup. (of course you have to target a PopupPage to make this works)

Reverse Dependency Service

I have a Xamarin Forms Project. I have used Dependency Service to call the Platform specific method to fire a local notification on Android and a Alert on iOS.
My problem is now, how to handle an action on both notification(android) and alert(iOS). Is it possible to call a method of the shared project from the android or iOS project?
Do I need another approach? Does someone know what I have to do?
Just for clarification, I know how the ordinary dependency services works i.e. Call a method on android or iOS from the shared project!
I believe I had a similar scenario on my app. If you want to push something from your platform methods to your PCL you would need to make use of call backs and event delegates.
In Interface PCL:
event OnMessageHandlerCallback OnMessageEvent;
event OnErrorHandlerCallBack OnErrorEvent;
In Platform specific Class inheriting interface:
private OnMessageHandlerCallback callback = null;
private OnErrorHandlerCallBack errorCallBack = null;
public event OnMessageHandlerCallback OnMessageEvent;
public event OnErrorHandlerCallBack OnErrorEvent;
Have you tried just calling the method from your native project...? No special patterns necessary. The native iOS and Android projects have a direct reference to your shared project, so it can call the method directly.

MvvmCross 4.x in shared project

I am totally new in developing with Xamarin and I try to use the MvvmCross library in a shared project for all platforms. It seems that I succesfully added the libraries in each project, but now I am confused how to start. I tried to follow the documentation, but I think I didnt understand it right. I can use the CreatableTypes Method, but there are no EndingWith or the other Methods from the documentation. The examples that I found are mostly about PCL. I even dont know if this is a version problem or if I missed something important at all. Any hint or link would be helpfull.
First of all be careful what informations you read, always check the date or you will waste your time with some articles which are outdated. The most important ressources are prolly the official sample: https://github.com/MvvmCross/MvvmCross-Samples
Normally you use the PCL for all the background stuffand there should be some class like this https://github.com/MvvmCross/MvvmCross-Samples/blob/master/TipCalc/TipCalc.Core/App.cs . In this class you should be able to register all your services like this for IoC:
public override void Initialize()
{
CreatableTypes().EndingWith("Service").AsInterfaces().RegisterAsSingleton();
And then MVVMCross automatically takes care of initializing it, if you do a constructor injection in the ViewModel as a Example...
public MainViewModel(IPreferenceService preferenceService)
{
// Do Something here with the Service
}
...and you just need to call to show it with it connected view:
ShowViewModel<MainViewModel>();
So basically try to understand the samples first, i think TipCalc is still mostly up to date, atleast it is MVVMCross 4.0 https://github.com/MvvmCross/MvvmCross-Samples/tree/master/TipCalc

Resources