MVVM-light There is already a factory registered for INavigationService - windows-phone-7

I'm trying to adjust my WP8 project from self made MVVM implementation to MVVM Light.
The application compiles without errors, but when I open my MainPage.xaml in Expression Blend, I will get this error:
Class project.Services.INavigationService is already registered. App.xaml
My ViewModelLocator.cs:
/// <summary>
/// Initializes a new instance of the ViewModelLocator class.
/// </summary>
public ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
if (ViewModelBase.IsInDesignModeStatic)
{
}
else
{
if (!SimpleIoc.Default.IsRegistered<INavigationService>())
{
SimpleIoc.Default.Register<INavigationService>(() => new NavigationService());
}
}
SimpleIoc.Default.Register<MainPage>();
SimpleIoc.Default.Register<SettingsEditViewModel>();
}
As you can see from my code comment, I've already tried the fix supposed here, but I'm still getting this error in Blend. There is no other place left where I could register the INavigationService, so what could be the problem?
Any ideas? :)

I had the same issue, and this seems to be a Visual Studio issue in combination with XAML-Designer, Static Factories/Locators and Design-Time creation of objects. However: The solutions were the following:
Register without a factory (not recommended)
SimpleIoc.Default.Register<INavigationService>();
Or if you want to use a factory, unregister before registering the factory
SimpleIoc.Default.Unregister<INavigationService>();
SimpleIoc.Default.Register<INavigationService>(() => new NavigationService());
Prevent the ViewModelLocator from being created more than once by the designer/Blend by making the constructor static
static ViewModelLocator() { ... }
The error is cumbersome but could happen in this scenario: You create objects during design-time (the ViewModelLocator within App.xaml probably) and whenever you change something in your Code, the Compiler is triggered and the ViewModelLocator gets re-created without ever unregistering the services. Therefore it will complain that in the factory has already been registered. In theory, when registering classes without factories multiple times, there should be an error as-well.

Might already be solved by now, but I think you can just solve the issue in your example case by not using the factory method override.
SimpleIoc.Default.Register<INavigationService, NavigationService>();
If you do need a factory method, then you can mix this line in with your factory method approach using the design mode check like you have been.
if (ViewModelBase.IsInDesignModeStatic)
{
SimpleIoc.Default.Register<INavigationService, NavigationService>();
}
else
{
SimpleIoc.Default.Register<INavigationService>(CreateNavigationService);
}

This seems like a super old question, but after hours of googling, this is the only question that's similar to my problem, so answering here for other people.
Make sure that you have IsDataSource on your ViewModelLocator:
<vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
That solved my problem and my design data popped up straightaway.
Weirdly, after putting that on, all my "INavigationService is already registered" errors goes away!

Not sure why, but I only get this error when my xaml designer window is open. When I compile with it closed, the error goes away and the project is built and runs successfully.

Related

MVVMCross View Model Prepare method not called when Hot Reload (ing) XAML changes

I started using MVVMCross several weeks ago and so far I love it, but I've noticed that whenever I'm working on the UI and making changes in the XAML and pressing save which activates the Hot Reload in Visual Studio 2019, I'm getting Null Reference Exceptions.
This is down to the fact that the MVVMCross' Prepare method is not getting called. According to their doc's this method is used to pass a parameter to the VM which can then be used throughout the VM.
public override void Prepare(MyClass param)
{
MyClass = param;
}
public override Task Initialize()
{
MyClass.DoSomething();
return base.Initialize();
}
So this is the basic usage (I think). However when I Hot Reload the XAML changes Prepare isn't called but Initialize is, which causes the Exception.
Is this a bug ?
Prepare in normal cases will only be called when calling NavigationService.Navigate.
What Hot Reload actually does is unclear. This use case is currently not officially supported by MvvmCross.

How to set FiddlerCore up to monitor all system traffic?

We are evaluating FiddlerCore for a use-case. Basically, for now we just want to catch all of the endpoints/urls being requested on a system. This works fine in Fiddler, no issues. But we only want to catch them while a certain vendor software is open. So we want to write a plugin to that software that will run when it launches, and then exit when it exits. Hence, using FiddlerCore (hopefully).
As proof-of-concept, I just made a simple app, one form with a textbox, that it should just append each url into the textbox. Simple as simple can be. However, it's not doing anything. I run the app, then refresh a page in my browser, and ... nothing.
Here is the entire (non-generated) code of my program...
using Fiddler;
using System;
using System.Windows.Forms;
namespace ScratchCSharp {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
FiddlerApplication.AfterSessionComplete += FiddlerApplication_AfterSessionComplete;
FiddlerApplication.Startup(8888, FiddlerCoreStartupFlags.Default);
}
private void FiddlerApplication_AfterSessionComplete(Session s) {
textBox1.Invoke((Action)delegate () {
AddText(s.fullUrl);
});
}
public void AddText(string text) {
textBox1.Text += $"{text}\n";
}
}
}
After a little more poking around, I see that FiddlerApplication.IsSystemProxy is returning false. Seems to have to do with that the Startup flag to set as system proxy is no longer honored, and it tells you now to use the Telerik.NetworkConnections.NetworkConnectionManager to set it as the system proxy. But I can't find anywhere that actually says how to do that. The closest thing I could find is this thread which seems to be their official answer to this question. However, it only goes into a lot of talk about WHY they deprecated the flag, and what their thinking was in how they designed its replacement, but not actually into HOW TO USE the replacement. The Demo app also does NOT use these libraries (probably why it doesn't catch anything either).
The biggest problem though, is that the NetworkConnectionsManager class has no public constructor, so you can't create an instance. It is not inheritable, so you can't make a subclass instance. All of the methods on it are instance methods, not static/shared. And there seems to be no method in the libraries which will create an instance of NetworkConnectitonsManager for you.
So while the class is clearly designed to be used as an instance (hence the methods not being static/shared, there doesn't actually seem to be any way to create an instance.
Any help on how to set this thing up to catch all the outgoing URLs on the system?
You can use the following code for starting Fiddler Core and registering it as a system proxy:
FiddlerCoreStartupSettings startupSettings =
new FiddlerCoreStartupSettingsBuilder()
.ListenOnPort(fiddlerCoreListenPort)
.RegisterAsSystemProxy()
.ChainToUpstreamGateway()
.DecryptSSL()
.OptimizeThreadPool()
.Build();
FiddlerApplication.Startup(startupSettings);
Some of the methods are obsolete for now, but I would recommend to stick with them until the NetworkConnectionManager API is improved and finalized.
Also, there is a sample application (that FiddlerCore installer installs on the Desktop), which is useful for a starting point with the development.

Xamarin: 'System.Resources.MissingManifestResourceException' on WinPhone

I found an issue with localization in WinPhone app. I added couple of resources and implemented localization. It is working fine in simulator, but crashing on Phone with exception Exception thrown: 'System.Resources.MissingManifestResourceException' in mscorlib.ni.dll
Any help?
Thanks to a bit of googling and a helpful blog post I have managed to solve this issue that happened intermittently with Xamarin.Forms projects.
This is the blog post that led me to the solution:
http://blog.tpcware.com/2016/06/xamarin-forms-localization/
Basically, the way you access resources on Android and iOS with Xamarin.Forms and Windows Phone is different:
To make it short, we need to “automagically” use the ResourceLoader.GetString(…) method when running on Store apps, while continuing to use the regular ResourceManager.GetString(…) method on all other platform. And because in the Xamarin Forms solution we use a resource file of type RESX, we also have the automatically generated resource class.
The super clever idea contained in the above linked post is to “hack” the resource class injecting a derived class of ResourceManager with an overridden GetString(…) method into the resource class “resourceMan” property (for a more detailed explanation of this hack, you can read the post).
We need to create our own version of ResourceManager like so and swap it for the existing ResourceManager using reflection:
public class WinRTResourceManager : ResourceManager
{
readonly ResourceLoader _resourceLoader;
private WinRTResourceManager(string baseName, Assembly assembly) : base(baseName, assembly)
{
_resourceLoader = ResourceLoader.GetForViewIndependentUse(baseName);
}
public static void InjectIntoResxGeneratedApplicationResourcesClass(Type resxGeneratedApplicationResourcesClass)
{
resxGeneratedApplicationResourcesClass
.GetRuntimeFields()
.First(m => m.Name == "resourceMan")
.SetValue(null, new WinRTResourceManager(
resxGeneratedApplicationResourcesClass.FullName,
resxGeneratedApplicationResourcesClass.GetTypeInfo().Assembly));
}
public override string GetString(string name, CultureInfo culture)
{
return _resourceLoader.GetString(name);
}
}
All that's then left to do is call this when the app starts for the first time:
WinRTResourceManager.InjectIntoResxGeneratedApplicationResourcesClass(typeof(AppResources));
After making these changes everything should work fine now.
Of course this is absolutely a hack but I have notified the Xamarin.Forms team of the issue and they are looking into it so hopefully it will be solved soon!

Strange MethodMissingException

I have stumbled upon interesting problem which is destroying me last couple of hours. I have project in VS, in references I have library Communication.dll, which contains class Service.
I am invoking following method:
public void ConnectPipe()
{
Service service = new Service();
service.ConnectionMode = ConnectionModes.PIPE;
service.Connect();
}
when I run it, on second line I get MissingMethodException - Method not found: 'Void Service.set_ConnectionMode()'
when I press F12 on service class, I get the Assembly info for the class. When I look for my property, setter is in place, so it does not look like problem with referenced library:
public ConnectionModes ConnectionMode { get; set; }
has anyone any idea where problem might be please?
Had the same issue. Fixed by updating reference to the library.
Point to the exact file on the local, through button "Browse..." don't choose from the library list in references manager - that doesn't work correctly sometimes.
And rebuild the referenced assembly.

"There is already an open DataReader..." error when using the Database.SetInitializer in the Global.Asax ApplciaitonStart

I am wondering if anyone else has had an issue with running the DB initializer from the global asax?
I have this in the ApplicationStart:
Database.SetInitializer(new MyInitializer());
That runs fine, after that once my application has started I try a login Method i created in my services. It fails when it tries to open the context.
My test application is setup almost the same way and doesn't have an issue.
Any thoughts?
Update:
I tried adding the MultipleActiveResultSets=True and now I am getting this error:
The underlying provider failed on Open.
Update 2:
Well, it turns out that my application loads while the initializer is still finishing. That is why I was getting those errors. So, what I figured out is that part of the app loads and then it must request something from the DB (at which point it created the DB and seeds it). At that point part of the application has loaded, but you don't know that the initializer is still running.
Like I sad in my updates, the DB wasn't getting created until after most of the application had run already. It was still running even though, as a user, you wouldn't know it. So I created an initialization project and added this class:
public static class InitializeAndSeed
{
public static void Initialize()
{
Database.SetInitializer(new MyContextInitializer());
using (var db = new MyContext())
{
db.Database.Initialize(false);
}
}
}
In my Applicaiton_Start() I call the InitializeAndSeed.Initialize(). Worked perfectly.
This article helped me figure that out.

Resources