WP7 Mango causes MissingMethodException in constructor - windows-phone-7

In my constructor of a class, I call a virtual member. Whether this should or should not be done is out of scope for my question.
WORKS (can call in my constructor):
protected void DoSomething();
protected virtual void DoSomething();
DOES NOT WORK
protected override void DoSomething();
The DOES NOT WORK part is located in the same library, the derived class has the same visibility, etc. As soon as I override the (virtual or abstract) DoSomething defined in class A in my Class B, I get a MissingMethodException as soon as the method is executed.
Does anyone have an idea why?

After lots of debugging, trying, etc, it seems that a class I used inside the method derived from an interface with this definition:
public interface IMyInterface<out TValueInterface>
It seems you cannot use covariant type parameters, otherwise you will get this exception.
For more information, see this blog post.

I think it's because you created the project with the beta 1 of the SDK.
Try again in a new project and you won't encounter the problem :-p !

Related

For a Xamarin Forms application how should I decide what goes in the App constructor or the OnStart()?

Here's the code that I have:
public App()
{
InitializeComponent();
DB.CreateTables();
DB.GetSettings();
DB.PopulateTables();
SetResourceColors();
SetResourceDimensions();
MainPage = new MainPage();
activity = Helpers.Activity.Create();
VersionTracking.Track();
DeviceDisplay.MainDisplayInfoChanged += OnMainDisplayInfoChanged;
}
protected override void OnStart()
{
}
Can someone explain to me. Is there any difference between me placing the code such as I have in the constructor or in the OnStart() method? What's the normal way to do this?
I have been working with Xamarin.Forms for a long time now and this is how I and my fellow developers use the OnStart Method.
If you check the Microsoft documents it says the following about it :
OnStart - Called when the application starts.
So, first of all, you should know that there is no specific use of the OnStart method, to be very honest there is no major difference in between using the constructor or this lifecycle method because both get called on XF framework startup, first the constructor then the OnStart method.
Now let's come to the differences.
As Jason pointed out, the OnStart method is a lifecycle method and hence has a return type unlike the constructor, so you can even call an asynchronous piece of code in the OnStart method but you cannot do the same in the constructor as constructors cannot be asynchronous.
Which means if you have the below method:
public async Task<bool> IsSomeThingWorkingAsync(//SomeParams)
{
// Code
}
Now, this method cannot be asynchronously called from the constructor since constructors are forcefully synchronous and have no return types. But if you try doing that from the on start method it's quite easy and it will work. In this case, you use the OnStart method. Something like below:
protected override async void OnStart()
{
bool WasWorkSuccess=await IsSomeThingWorkingAsync();
//do something with the boolean
}
A constructor is intended to be used for wiring. In the constructor, you want to avoid doing actual work. You basically prepare the class to be used. Methods are intended to do actual work.
Note: There are no performance gains whatsoever by choosing one over the other - it's really a matter of preference and standard.
Please go through the details here
You can write the initialisation codes in App() constructor. But you need to be very careful abut registering events.
Reason is,
For example in Android, If the app is launched and it is in task list and if you try to launch the app again by clicking on app icon. The constructor of App() will call again. This will register the event multiple times and will create issues.
So for events I will suggest you to use overriden methods for registering events.
Again as Jason pointed it out, It is your personal preference where to write your code.

Windows Service Implementing IDisposable - Is it bad practice?

I've come across this code:
public class ServiceLauncher2 : ServiceBase, IDisposable
And then this:
/// <summary>
/// Disposes the controllers
/// </summary>
// This is declared new as opposed to override because the base class has to be able to
// call its own Dispose(bool) method and not this one. We could just as easily name
// this method something different, but keeping it Dispose is just as valid.
public new void Dispose()
{
foreach (var mgr in _threadManagers)
mgr.Dispose();
base.Dispose();
}
I've never seen this in a Windows Service implementation before. Usually just OnStop/OnStart is overridden. Is this bad practice?
Let's count the ways this is bad practice:
The new keyword is grating, it tells the compiler to shut up about a potential problem in the code. A real one, the code that uses this class can easily end up calling ServiceBase.Dispose() instead. ServiceBase implements the disposable pattern, the correct way to do it is to override the protected Dispose(bool) method
The Dispose() method leaves a _threadManagers collection object behind that contains nothing but dead objects. Which makes the collection dead as a doornail as well, iterating it afterwards is meaningless. It should have been emptied
The only time this Dispose() method can be called is at service termination. Can't do it in OnStop(), it also disposed the ServiceBase. Disposing "controllers" a microsecond before the finalizers run and the process terminates makes no sense. Dispose() should only ever be used to allow unmanaged resources to be de-allocated early. There is no early when the process stops a millisecond later
This code makes no sense. Don't use it.
It does look non-standard but it is legit. So I wouldn't necessarily call it bad practice, though the fact that it introduces confusion makes it bad practice?
Does this run only as a service or is there console mode? (Console app would not get OnStop called.) Or is there some other (custom) way to stop this service process?
Ammending from my own earlier question of:
I'm not sure why new instead of override, especially since
base.Dispose() is being called.
Reason:
'SomeClass.Dispose()': cannot override inherited member
'System.ComponentModel.Component.Dispose()' because it is not marked
virtual, abstract, or override
In other words, the implementaion of ServiceBase.Dispose is not overridable.
Just to add to the already perfect answers by Hans and Paul: declaring ServiceLauncher2 as IDisposable is redundant, as ServiceBase is a Component which in turn is already IDisposable

Ninject: Choosing the wrong constructor

I have an ASP.NET MVC 3 application with Ninject v2.2.1.4. Everything was working great and then suddenly we started seeing Ninject attempting to create our DbContext using a constructor with a parameter over the parameterless constructor. Here are the bindings:
kernel.Bind<MyContext>().ToSelf().InRequestScope();
kernel.Bind<IUnitOfWork>().ToMethod(ctx => ctx.Kernel.Get<MyContext>());
kernel.Bind<DbContext>().ToMethod(ctx => ctx.Kernel.Get<MyContext>());
The MyContext is a DbContext object that implements the IUnitOfWork interface as well. I have set it up this way so the same context is injected into multiple repositories that are used in a single request. The MyContext constructors look like this:
public MyContext() { }
public MyContext(string connectionString) { }
public MyContext (long accountID) { }
public MyContext (Connection connection) { }
There are different constructors for different applications as they all use the same MyContext class. Looking at the bindings you would think when a MyContext class was requested that the parameterless constructor would be called but for whatever reason, it is not. The one with the long accountID parameter is called even though no accountID is being specified. This obviously throwns and exception statement that "No matching bindings are available, and the type is not self-bindable" It actually throws the exception when trying to generate a IUnitOfWork.
If I comment out the last three constructors everything works fine and the parameterless constructor is used. If I comment out any two of the parameterized constructors it tries to use the other and not the parameterless one.
The suggestions provided by Ninject are:
Suggestions:
1) Ensure that you have defined a binding for long.
2) If the binding was defined in a module, ensure that the module has been loaded into the kernel.
3) Ensure you have not accidentally created more than one kernel.
4) If you are using constructor arguments, ensure that the parameter name matches the constructors parameter name.
5) If you are using automatic module loading, ensure the search path and filters are correct.
We don't have anything for 1 as we don't want to. I'm not sure what 2 and 5 mean. I do not believe we have done 3 and we are not doing 4.
Any thoughts as to why it wouldn't use the parameterless constructor in this scenario.
#Xander's answer is right in general but Ninject has some very specific solutions in V3.
Ninject scores constructors by a specific algorithm which is to find the one with the most parameters it knows how to resolve as documented in this wiki article [which claims to be for V2.4, which was actually badged 3.0]. See the code. I think this is also on the wiki. If it's not, someone should put it there.
RE the change in behavior you've seen, the chances are either Implicit Self Binding is changing the goalposts (new registrations are being added during resolution) or you've added a Binding that has made one of the other constructors more attractive.
The [Inject] attribute trumps all other criteria which is what you're after (although you don't actually want to have container specific attributes in your code).
The WithConstructorArgument technique suggested is actually effected by using ToConstructor - doing a WCA will not influence the selection (and I reckon you won't get complaints about the redundant specifications.
The real bottom line is that you should never end up in as big a mess as this as alluded to in #Mark Seemann's comment on this related question.
Sadly, the above is all a lie. If you move off v2.2, this answer will become correct. If you can't or won't, you need to look at the equivalent source and tests to find out the rules from before that (from memory (and some google code that appeared in search results in my research), it was based on the constructor count, but not sure how equal scores are disambiguated.
Pretty sure that in 2.2, adding an [Inject] is the quick way out.
By default Ninject, along with other similar IoC frameworks, chooses the constructor with the most parameters. Specify which constructor to use during the initialization by the WithConstructorArgument extension method.
kernel.Bind<DbContext>()
.WithConstructorArgument("connectionString",
ConfigurationManager.ConnectionStrings["connection"]
.ConnectionString)
.ToMethod(ctx => ctx.Kernel.Get<MyContext>());
To force Ninject to use the default constructor place the [Inject] attribute on the constructor:
[Inject]
public MyContext() { }

Handling metro event in native c++ class

I would like to handle a button clicked event in a native c++ class. I have tried creating a 'handler' object derived from Object to handle the event and then calling a c++ method. For example I tried the following code:
ref class GButtonHandler sealed : public Object
{
public:
void Button_Click(Object^ sender, RoutedEventArgs^ e)
{
}
GTextBlockHandler(GButtonImpl * pButtonImpl, Button ^ button)
{
button->Click += ref new RoutedEventHandler(this, &GTextBlockHandler::Button_Click);
}
};
Thinking that I could squirrel away the pButtonImpl pointer and then use it to call a native function in the Button_Clicked function. However on compiling this code, I get the error:
error C3986: '{ctor}': signature of public member contains native type 'GButtonImpl'
So it seems that it does not like me passing in native classes into an ref object. Is there a way to do this?
Note that I am completely new to developing Metro style apps, so bear with me!
Ok, it all makes sense to me now. For anyone else who is interested, the reason you cannot have WinRT Objects with public functions that have native C++ arguments is that these objects would then not be consumable by non C++ code. However, the (obvious?) solution is to make the constructor private and have the class that creates the Object declared as a 'friend' class (duh!). Then all is well, the compiler is happy, and I am happy.
Thanks to all who took the time to read this.
The correct answer is to use internal rather than public for the constructor. This tells the compiler that it will only be available in the current project, and won't be available to external projects (i.e. a library written in another language).

Visual Studio 2010 Extension - events not called

I trying to hook several Visual Studio events. Unfortunately I am failing in the first step. The event handlers are never called.
So my question is what I am doing wrong?
Here a little excerpt of my code.
// here are some attributes
[ProvideAutoLoad(VSConstants.UICONTEXT.SolutionExists_string)]
public sealed class VSPackage : Package {
EnvDTE80.DTE2 dte_;
EnvDTE.DocumentEvents documentEvents_;
EnvDTE.WindowEvents windowEvents_;
public VSPackage2Package() {
Trace.WriteLine("I am get called.");
}
protected override void Initialize() {
Trace.WriteLine("I am get called too.");
dte_ = (EnvDTE80.DTE2) System.Runtime.InteropServices.Marshal.
GetActiveObject("VisualStudio.DTE.10.0");
windowEvents_ = dte_.Events.WindowEvents;
documentEvents_ = dte_.Events.DocumentEvents;
windowEvents_.WindowCreated +=
new EnvDTE._dispWindowEvents_WindowCreatedEventHandler(
windowEvents_WindowCreated);
documentEvents_.DocumentOpened +=
new EnvDTE._dispDocumentEvents_DocumentOpenedEventHandler(
documentEvents__DocumentOpened);
Trace.WriteLine("Everything fine until here.");
}
void documentEvents__DocumentOpened(EnvDTE.Document document) {
Trace.WriteLine("Never called");
}
void windowEvents_WindowCreated(EnvDTE.Window window) {
Trace.WriteLine("Never called");
}
}
Edit:
I get it working, looking at other sample code, I figured out that they sometimes getting the DTE object differently. Changing
dte_ = (EnvDTE80.DTE2) System.Runtime.InteropServices.Marshal.
GetActiveObject("VisualStudio.DTE.10.0");
to
dte_ = GetService(typeof(EnvDTE.DTE)) as EnvDTE80.DTE2;
and now everything is fine.
It should work.
I'm pretty sure that if you do the same from an Addin it would work. Packages can be painfull sometimes.
In fact, when a package is loaded the shell (DTE) may not be fully loaded yet. Try to register your events when it is.
To do so, use the OnShellPropertyChange event and the Zombie state to know when to register.
http://social.msdn.microsoft.com/forums/en-US/vsx/thread/3097a0e1-68e3-47ea-a4ba-8511571b2487/
Read the following, I think it answers your question. Note : The GetService method is the same as calling GetGlobalService.
1. ServiceProvider.GlobalProvider
This new static property on the
ServiceProvider class allows access to
the global service provider from any
code, as long as it is called from the
main UI thread. This property is
closely related to the
Package.GetGlobalService static method
which was available in previous
versions of the MPF. The problem with
Package.GetGlobalService was that it
would fail if a package had not yet
been initialized. This led to subtle
ordering bugs in code that used the
MPF libraries without initializing a
package of their own. Sometimes they
would work only because another
package had already initialized the
global ServiceProvider on their
behalf. If that other package was
uninstalled, or perhaps moved to a
different version of the MPF, that
static would no longer be initialized
causing Package.GetGlobalService to
fail.
Now, in MPF 10, you can call
ServiceProvider.GlobalProvider at any
time as long as you are calling from
the UI thread. For compatibility, this
mechanism will still use the
ServiceProvider created by the first
Package to be sited but, in the case
where no Package has yet been
initialized, MPF 10.0 now has the
ability to obtain the global provider
from the registered COM message
filter. Package.GetGlobalService() is
also hooked up to this new mechanism.
Make sure you are not boxing and unboxing your DTE object. I found this was the issue for me.
See my solution here: http://social.msdn.microsoft.com/Forums/en-US/vsx/thread/eb1e8fd1-32ad-498c-98e9-25ee3da71004

Resources