I would like to define a custom presenter to customise my UI a little, to implement a split view on iPad and so on. I defined this class:
class ProjectPresenter : MvxTouchViewPresenter
{
public ProjectPresenter(UIApplicationDelegate applicationDelegate, UIWindow window) : base(applicationDelegate, window)
{
}
public override void Show(MvxViewModelRequest request)
{
IMvxTouchView viewController = this.CreateViewControllerFor(request);
this.Show(viewController);
}
}
And I registered it in my MvxTouchSetup class like so:
protected override IMvxTouchViewPresenter CreatePresenter()
{
MvxTrace.Trace("Creating the presenter!");
return new ProjectPresenter(this.ApplicationDelegate, this.Window);
}
However, breakpoints in the Show() method are never hit. I tried adding breakpoints to all overloads of Show(), ChangePresentation(), etc, but they are never hit. Now, I know that Xamarin.iOS is fairly unreliable where breakpoints are concerned but even putting in trace methods yields no joy. I even replaced the CreatePresenter() method with a method that throws an exception and the app didn't crash.
Other modifications to my application show up when I deploy them, so this isn't some sort of caching problem, although I have cleaned both the sources on my PC and on my Mac as well. Furthermore, the breakpoint in the constructor of my setup class is being hit, so this is perhaps not even a Xamarin-related problem at all.
I'm guessing that I'm either relying on older documentation or I'm doing something very very silly (I'm guessing the latter).
The only reason I can think that CreatePresenter wouldn't be called is if you are using the older 'presenter-based' constructor for your Setup
MvxTouchSetup provides two different constructors:
protected MvxTouchSetup(MvxApplicationDelegate applicationDelegate, UIWindow window)
{
_window = window;
_applicationDelegate = applicationDelegate;
}
protected MvxTouchSetup(MvxApplicationDelegate applicationDelegate, IMvxTouchViewPresenter presenter)
{
_presenter = presenter;
_applicationDelegate = applicationDelegate;
}
from https://github.com/MvvmCross/MvvmCross/blob/v3/Cirrious/Cirrious.MvvmCross.Touch/Platform/MvxTouchSetup.cs#L39
By default in Nuget-based projects and in most of the MvvmCross samples, the first of these is used.
However, the second form actually existed first and so it's still around for historical reasons - to prevent older apps from breaking. If you use it, then the CreatePresenter() is not used - it's not needed because you've supplied a presenter during construction.
Related
One would think that in C# 8.0 you should be able to do the following (according to this (1st snippet)):
public interface IRestApiClient : IRestClient
{
...
Task<T> PostPrivateAsync<T>(string action, OrderedDictionary<string, object> parameters = null, DeserializeCustom<T> deserializer = null)
{
return QueryPrivateAsync(Method.POST, action, parameters, deserializer);
}
...
}
public class SpecificClient : ExchangeClient, IRestApiClient, IRestHtmlClient, ISeleniumClient, IWebSocketClient
{
}
The example above won't compile because the interface members need to be explicitly and wholly implemented (including the methods supplying the default logic)
So one would think that the following should work:
public interface IRestApiClient : IRestClient
{
...
Task<T> PostPrivateAsync<T>(string action, OrderedDictionary<string, object> parameters = null, DeserializeCustom<T> deserializer = null)
{
return QueryPrivateAsync(Method.POST, action, parameters, deserializer);
}
...
}
public class SpecificClient : ExchangeClient, IRestApiClient, IRestHtmlClient, ISeleniumClient, IWebSocketClient
{
...
public async Task<T> PostPrivateAsync<T>(string action, OrderedDictionary<string, object> parameters = null, DeserializeCustom<T> deserializer = null)
=> await ((IRestApiClient) this).PostPrivateAsync(action, parameters, deserializer);
...
}
Nope, it looks like this method is recursive (despite the upcast) and will cause our favorite Stack Overflow exception.
So my question is (abstracting from the fact that I could change the design in my example), is there a way of keeping the implementation for a specific method default, preferably without the necessity of resorting to hacky or Static Helper Extension methods? I could call static extension method in both interface and the class but it kind of defeats the purpose of this feature.
// EDIT
I must admit it confuses me and it appears I am missing something critical that is obvious to other people. I didn't provide additional info because I didn't consider my issue to be code specific. Lets look at this simple example (taken from the website I linked on the beginning of my post):
According to #Panagiotis Kanavos comment: No, default members don't need to be implemented (...) what I screenshoted should not be true. Can sb please enlighten me?
// EDIT 2
As you can see I am properly targeting .NET CORE 3.0 with C# 8.0.
ERRORS:
Interface method cannot declare a body
Interface member 'void CryptoBotCoreMVC.IDefaultInterfaceMethod.DefaultMethod()' is not implemented
To answer the question in the comments: I didn't specify LangVersion explicitly in the .csproj file.
// EDIT 3
The issue was ReSharper, see:
https://stackoverflow.com/a/58614702/3783852
My comment have been deleted, presumably by the owner of the answer so I'll write it here: the clue was the fact that there was actually no error numbers, but the compilation was blocked. It turned out that there is an option to block compilation when these errors occur in ReSharper.
It seems that in the end this is a possible duplicate, but getting to this conclusion was quite a journey :).
The issue is caused by ReSharper, reference:
https://youtrack.jetbrains.com/issue/RSRP-474628
It appears that the problem will be resolved in version v2019.3 and we currently have v2019.2.3. You can setup ReSharper to block compilation depending on issue severity, the workaround is to disable this feature for the time being.
I am trying to create a custom manager which is passed in the controller when it is being called and I am having troubles understanding the current implementation of new MVC5 project in c#.
Here is the default implementation:
public AccountController(ApplicationUserManager userManager, ApplicationSignInManager signInManager )
{
UserManager = userManager;
SignInManager = signInManager;
}
above all of that are declarations for them:
public ApplicationSignInManager SignInManager
{
get
{
return _signInManager ?? HttpContext.GetOwinContext().Get<ApplicationSignInManager>();
}
private set
{
_signInManager = value;
}
}
public ApplicationUserManager UserManager
{
get
{
return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
private set
{
_userManager = value;
}
}
Now from my understanding the SignInManager and UserManager get created when application gets created for the first time in Startup.Auth.cs which looks like this:
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
So now whenever I call UserManager I will get that first instance that was created when project ran for the first time.
I have 2 questions. Question 1 is is anything I said above wrong and Do I have a wrong understanding of how MVC5 works?
Question2: How is UserManager and SignInManager generated and passed in the controller? Where is the code that creates that first instance of the manager and passes it in the controller? I am assuming it is app.CreatePerOwnContext that does it. If so, can I then just create my own Manager and then register it with Owin in the same fashion and reuse throughout the project? Will my code get the latest data from the database if I do this and not cache it?
The code you're showing is coming from the IMO very ugly MVC5 template, which works out of the box but does some ugly things.
This constructor:
public AccountController(ApplicationUserManager userManager,
ApplicationSignInManager signInManager)
makes you think OWIN automagically injects the managers for you. But in fact this is not the case. That is why the template comes with the ugly properties you supplied in the questions. When you do not change anything to the template, the default constructor is called (also present in the template). To try it, just delete, or comment, the default constructor and you'll see the AccountController can't be created anymore.
So what is actually happening there is that both managers are located using the Service Locator anti pattern in the getters of the supplied properties.
So now whenever I call UserManager I will get that first instance that was created when project ran for the first time?
No this is not the case. What this line:
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
does, is creating a delegate to the Create method of both managers. The managers are cached within an Owin Request. The next request the delegates are called again and you get a fresh ApplicationUserManager etc.
To be a little bit more verbose this line could be rewritten as:
Func<ApplicationUserManager> userManagerFactory = () => ApplicationUserMangager.Create();
app.CreatePerOwinContext<ApplicationUserManager>(userManagerFactory);
So if you would a breakpoint here:
public ApplicationUserManager UserManager
{
get
{
// place breakpoint here
return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
// ....
You would see that while stepping through the code, you will hit the line where you created the UserManagerFactory which in his turn will call the Create() method of the ApplicationUserManager.
How is UserManager and SignInManager generated and passed in the controller
It isn't! You would need to use dependency injection for that.
If so, can I then just create my own Manager and then register it with Owin in the same fashion and reuse throughout the project
Yes you can. You can completely refactor the ApplicationUserManager you also got 'for free' in the template. As long as you supply a factory method to the 'CreatePerOwinContext' extension method.
Will my code get the latest data from the database if I do this and not cache it?
The instances are cached on per request base. So each request you will get a new one, with a new DbContext etc.
I'm unsure how familiar you are with dependency injection but MVC5 is a pretty easy framework to start with it, IMO.
I once wrote a blogpost how to configure my DI container of choice (Simple Injector) to use with the MVC5 template.
I also wrote several answers here on SO regarding this template: specifically this one, should interest you. This one is interesting also!
I'm having trouble synchronising my GEF editor with the EMF-based model. I think this is due to the fact that the model-internal EMF Adapter, or rather the methods it calls, aren't finished before the editor's Adapter's notifyChanged() is called and updates the model children. This leads to the editor view being out-of-sync with the model itself, or rather, the changes to the model not being represented in the view when they should be.
Consider this set up. A Command "CreateNodeCommand" adds a node to the underlying model:
#Override
public void execute() {
...
getNewNode().setGraph(getGraph());
...
}
The GraphEditPart has an internal class extending org.eclipse.emf.common.notify.Adapter. It's notifyChanged() method is indeed notified, as tested similar to below (incomplete code):
#Override
public void notifyChanged(Notification notification) {
switch (notification.getEventType()) {
case Notification.ADD:
System.err.println("ADD occurred!");
refreshChildren();
}
The problem is, that the (third-party) model itself also implements an Adapter, which in turn runs a number of methods on the new model element, such as adding an ID, etc.
It seems to me that the fact that the new element's figure doesn't show up in the editor directly after it's been created - but only after the next editing step, the figure for which then doesn't appear - suggests that the model adapter is still busy setting up the new element while refreshChildren() is already being called by the editor adapter.
This seems to call for synchronisation, but I'm unsure whether this can be achieved with built-in Java functionality for multithreading, or calls for an EMF-based approach.
Please share your knowledge about synchronising in EMF.
Many thanks in advance!
EDIT
On request, here is the source code for the getModelChildren() method:
#Override
protected List<EObject> getModelChildren() {
List<EObject> allModelObjects = new ArrayList<EObject>();
allModelObjects.addAll(((MyGraph) getModel()).getTokens());
allModelObjects.addAll(((MyGraph) getModel()).getNodes());
return allModelObjects;
}
Debugging the (3rd party) model, I found out that the Graph's enotify() fired the notification before the actual adding took place, hence my Adapterreceived the notification too early, i.e., before the node had been added.
The notification is now called after the add and everything works fine.
Thanks for all of your help!
Try extending EContentAdapter instead of AdapterImpl, and not forget to call
super.notifyChanged(Notification notification);
in it. It's an adapter, which will add itself to new elements of the model, and notify you then they are changed.
I'm having issues with my Application Object. I am currently using a Service to simulate incoming data from an electronic game board. This data is represented as a 2D boolean array. Every five seconds the Service uses a method of the Application Object to update the array (setDetectionMap()). This array is being read by a Thread in my main Activity using another method (getDetectionMap()). After some debugging I am almost positive that the main Activity is not seeing the changes. Here is the code for my Application Object:
public class ChessApplication extends Application{
private static ChessApplication singleton;
private boolean[][] detectionMap;
public static ChessApplication getInstance(){
return singleton;
}
#Override
public void onCreate() {
super.onCreate();
singleton=this;
detectionMap=new boolean[8][8];
}
public boolean[][] getDetectionMap(){
return detectionMap;
}
public void setDetectionMap(boolean[][] newMap){
detectionMap=newMap;
Log.d("Chess Application","Board Changed");
}
}
I've checked my Manifest, I've rewritten my object declaration a dozen times, I've added LogCat tags to make sure that the code is executing when I think it should be, and I've even implemented the supposedly redundant Singleton code. Any ideas what could be causing this? Incidentally can anyone tell me how to view variable states as the activity is running? Thanks in advance.
Is your Activity calling getDetectionMap() to get the new map after the update occurs?
Because otherwise, it's holding onto a reference to the old boolean[][] array, wheras setDetectionMap(...) isn't actually updating the current data structure, it's just updating the "detectionMap" variable to point to a different one. As such, your main activity won't be aware of the swapout until the next time it calls getDetectionMap.
Easy fix: in setDetectionMap, manually copy values from newMap into detectionMap. Or, update the Activity's reference so it's looking at the right map.
One other observation entirely unrelated to the original question: It's quite unusual to override Application during Android development, and is usually considered a "code smell" unless you have a really good reason for doing so. In this case I imagine it's so that you can communicate between your service and Activity, but you create a middle-man where one isn't entirely necessary. Here's a useful SO thread on how to communicate directly between the two :)
I am having problems with the following class in a multi-threaded environment:
public class Foo
{
[Inject]
public IBar InjectedBar { get; set; }
public bool NonInjectedProp { get; set; }
public void DoSomething()
{
/* The following line is causing a null-reference exception */
InjectedBar.DoSomething();
}
public Foo(bool nonInjectedProp)
{
/* This line should inject the InjectedBar property */
KernelContainer.Inject(this);
NonInjectedProp = nonInjectedProp;
}
}
This is a legacy class which is why I am using property rather than constructor injection.
Sometime when the DoSomething() is called the InjectedBar property is null. In a single-threaded application, everything runs fine.
How can this be occuring and how can I prevent it?
I am using NInject 2.0 without any extensions, although I have copied the KernelContainer from the NInject.Web project.
I have noticed a similar problem occurring in my web services. This problem is extremely intermittent and difficult to replicate.
First of all, let me say that this is wrong on so many levels; the KernelContainer was an infrastructure class kept specifically to work around certain limitations in the ASP.NET WebForms page lifecycle. It was never meant to be used in application code. Using the Ninject kernel (or any DI container) as a service locator is an anti-pattern.
That being said, Ninject itself is definitely thread-safe because it's used to service parallel requests in ASP.NET all the time. Wherever this NullReferenceException is coming from, it's got little if anything to do with Ninject.
I can think of two possibilities:
You have to initialize KernelContainer.Kernel somewhere, and that code might have a race condition. If something tries to use the KernelContainer before the kernel is fully initialized (possible if you use the IKernel.Bind methods instead of loading modules as per the guidance), you'll get errors like this. Or:
It's your IBar implementation itself that has problems, and the NullReferenceException is happening somewhere inside the DoSomething method. You don't actually specify that InjectedBar is null when you get the exception, so that's a legitimate possibility here.
Just to narrow the field of possibilities, I'd eliminate the KernelContainer first. If you absolutely must use Ninject as a service locator due to a poorly-designed legacy architecture, then at least allow it to create the dependencies instead of relying on Inject(this). That is to say, whichever class or classes need to create your Foo, have that class call kernel.Get<Foo>(), and set up your kernel to Bind<Foo>().ToSelf().