System.InvalidCastException when calling a class which extends application - c#

I am working on an Android c# app where I have an class extends from Application called MyApplication. Inside MyApplication file, I have this method called getDataFromDB(). I am trying to call this method from my Activity but I am getting this exception during runtime:
System.InvalidCastException:
MyApplication.cs
public class MyApplication : Application
{
public MyApplication(IntPtr handle, JniHandleOwnership ownerShip) : base(handle, ownerShip)
{
}
public override void OnCreate()
{
base.OnCreate();
getDataFromDB();
}
public void getDataFromDB()
{ // code
}
}
Activity.cs
MyApplication application = ((MyApplication)this.ApplicationContext); //here's the location of the exception
application.getDataFromDB();
I don't have a clue why this exception is thrown. It doesn't seems to me that my casting is wrong. Would you please help me ?

The ApplicationContext is not necessarily the same object as the Application instance. I've seen this most often in emulators, but it can also be device specific.
In a Java app, you could cast the object returned by Activity#getApplication(). But according to a post on the Xamarin forum, an equivalent method does not exist in Xamarin. Instead, you can cast the Application property:
MyApplication app = (MyApplication) Application;
I'm not sure when the property is set, so this may not work in a field initializer.
Another option is to have MyApplication save a static reference to itself in OnCreate(), and provide a static getter. Although static fields are usually evil, this works because the Application instance is effectively a singleton, and its OnCreate will be called before any other component is created. The static reference can't leak the application because the application already has the same lifetime as the process.

Well, I solved it out by removing the Arguments of the contructor of MyApplication like that:
public class MyApplication : Application
{
public MyApplication() : base(handle, ownerShip) //here's the editing location
{
}
public override void OnCreate()
{
base.OnCreate();
getDataFromDB();
}
public void getDataFromDB()
{ // code
}
}
Then I called the Application:
MyApplication application = new MyApplication();

Related

Access to singleton instance fails with derived class

I have a database wrapper code like this (pseudo code):
class MyDBWrapper<objecttype> : Singleton
{
private DBDriver _Driver
Driver => Instance._Driver;
... tons of static functionality here referencing the driver
}
and then I can create custom databases from it:
class ObjectA_DB : MyDBWrapper<ObjectA_Type>
{
... all my calls using the static functionalities of the base class
}
this works very well...
Now, comes a different scenario:
I have a generic object: BaseObject
and a bunch of derived objects: ObjectA, ObjectB, etc
and they all require the same database code, so I did that:
class MyGenericDB<T> : MyDBWrapper<T> where T : BaseObject
{
.. common functionality
}
and then instantiated the type specific classes like this:
class MyTypeA_DB : MyGenericDB<ObjectA_Type>
class MyTypeB_DB : MyGenericDB<ObjectB_Type>
and this compiles properly, however the singleton code is causing problem when I try to access the instance
as it seems like it's recursing. Visual studio is unable to give a proper error as to what happens, but it hangs then crashes, so I am guessing a stack overflow.
The singleton code is here:
public abstract class Singleton<T> where T : class
{
private static readonly Lazy<T> _Instance = new Lazy<T>(CreateInstanceOfT, LazyThreadSafetyMode.PublicationOnly);
protected static T Instance => _Instance.Value;
private static T CreateInstanceOfT()
{
return Activator.CreateInstance(typeof(T), true) as T;
}
}
Did I miss anything obvious?
Not that used to this version of generics as my main work is in unity, and they update their core every decade, but I am pretty sure that you need your instance to be public to be allowed to read it.
When I write this, I traditionally create a private static instance of the passed type, and follow that up with a public static access function that creates that type if it does not yet exist.
A good full example for my own main engine can be found here:
http://wiki.unity3d.com/index.php/Singleton.

how to use static object in another project using api function

there are similar questions here but this one is specific. I have a solution and in it two projects. Main project and run time project, in order to use run time project i need to add reference to it in main project. In run time project i need to use static object from main project, in order to do that i need to add reference which i cant to because there would be circular dependence. I read that i could use API function how can I implement that?
Thanks.
namspace mainProject
{
public static MyClass Object;
}
public sealed class RuntimeComponentClass : IBackgroundTask
{
BackgroundTaskDeferral _deferral;
public void Run(IBackgroundTaskInstance taskInstance)
{
_deferral = taskInstance.GetDeferral();
//here i need to access static object from main project
_deferral.Complete();
}
}
First thing is that you cannot declare a static object just inside the namespace. I am assuming you have a class declared inside the namespace and static object is a member of that class
if you have following
namspace mainProject
{
public class AStaticClass{
public static MyClass Object;
}
}
you can definitely access the public static member from other classes.
public sealed class RuntimeComponentClass : IBackgroundTask
{
BackgroundTaskDeferral _deferral;
public void Run(IBackgroundTaskInstance taskInstance)
{
_deferral = taskInstance.GetDeferral();
AStaticClass.Object is accessible
//here i need to access static object from main project
_deferral.Complete();
}
}
However this is not a good idea to have static public member if you have any multi threading scenario.
This is in support of my comment on the original post.
I we solved the problem by moving all the classes in run time component project, in this way that one reference that exists is enough. Thanks everybody!

Unable to initialize iOS AppDelegate.cs with XFormsApplicationDelegate

I am creating an iOS application using Xamarin.Forms.Labs.iOS library.
I followed the steps as presented in this link https://github.com/XLabs/Xamarin-Forms-Labs/wiki
and replaced
UIApplicationDelegate
with
XFormsApplicationDelegate
in my AppDelegate.cs.
Here is my AppDelegate.cs :
[Register("AppDelegate")]
public partial class AppDelegate : XFormsApplicationDelegate
{
UIWindow window;
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
Forms.Init();
window = new UIWindow(UIScreen.MainScreen.Bounds);
window.RootViewController = App.GetMainPage().CreateViewController();
window.MakeKeyAndVisible();
return true;
}
}
and my Main.cs file has
public class Application
{
// This is the main entry point of the application.
static void Main(string[] args)
{
// if you want to use a different Application Delegate class from "AppDelegate"
// you can specify it here.
UIApplication.Main(args, null, "AppDelegate");
}
}
Is there anything wrong in my implementation ? I added all the assemblies and the code compiles without any errors. The app won't start and crashes with the following exception.
Objective-C exception thrown. Name: NSInternalInconsistencyException Reason: Unable to instantiate the UIApplication delegate instance. No class named AppDelegate is loaded.
Kindly, guide me in the right direction.
Thanks.
This is so silly. I just had to do rebuild instead of build to make that work.

Fire-and-forget approach on MEF plugin architecture

This question might be design related or code related, but I'm stuck so I'm open to any kind of answer; a pointer in the right way!
I have used MEF (Managed Extensibility Framework) to develop a piece of WPF software that will act as a form of orchestrator for plugins. The application is simply redirecting data between the plugins as of the users choice, so what the plugin does is not known at all (especially since they can be developed by 3rd party devs).
The application and the plugin are sharing an interface as a way of knowing what methods to call for, so the traffic goes both ways: a plugin calls a method in the main application sending it data and the main application is passing this data to another plugin.
This works so far, but I'm having a problem with synchronous behavior. All methods defined by the interface lack a return value (Void) and I'm struggling to get a "fire and forget" kind of approach where the calling application does NOT need to sit around waiting for the plugins receiving function to finish execute code (and calls that goes back to the main app!).
So whats the best approach to solving this? Letting every plugin (and the main app) put it's workload on a "stack" of some kind just to be able to return the control to the calling side and then have some mechanism that runs separately that works through the stack item by item (and do this stacking approach as async?)?
Other things worth noting is that the plugins are running in separate threads (according to the debugger thread window) and when they are initialized they get a reference from the calling main application so they can fire functions in the main app. The plugins also very often need to tell the main app what status they are in (idle, working, error etc) and also send data to be logged by the main app, so this very often creates a nested call hierarchy (if you follow me, hard to explain).
I'm using .Net 4.5 for this one.
Below is some simplified example of the code. I replaced some names, so if there is a spelling error somewhere, its just here and not in the real code. :)
The interface:
public interface IMyPluggableApp
{
void PluginStatus(string PluginInstanceGuid, PluginInstanceState PluginInstanceState);
void DataReceiver(string PluginInstanceGuid, string ConnectorGuid, object Data);
void Logg(string PluginInstanceGuid, LoggMessageType MessageType, string Message);
}
public interface IPluginExport
{
PluginInfo PluginInfo { get; set; }
void Initialize(string PluginInstanceGuid, Dictionary<string, string> PluginUserSettings, IMyPluggableApp MyPluggableApp);
void Start(string PluginInstanceGuid, List<ConnectorInstanceInfo> ConnectedOutputs);
void Stop(string PluginInstanceGuid);
void PluginClick(string PluginInstanceGuid);
void PlugginTrigger(string ConnectorGuid, object Data);
}
The plugin:
public static IMyPluggableApp _MyPluggableApp
[PartCreationPolicy(CreationPolicy.NonShared)]
[Export(typeof(IPluginExport))]
public class PluginExport : IPluginExport
{
public void Initialize(string PluginInstanceGuid, Dictionary<string, string> pluginUserSettings, IMyPluggableApp refMyPluggableApp)
{
_MyPluggableApp = refMyPluggableApp; // Populate global object with a ref to the calling application
// some code for setting saved user preferences
_MyPluggableApp.PluginStatus(PluginInfo.PluginInstanceGuid, PluginInstanceState.Initialized); // Tell main app we're initialized
}
public void Start(string PluginInstanceGuid, List<ConnectorInstanceInfo> ConnectedOutputs)
{
// Some code for preparing the plugin functionality
_MyPluggableApp.PluginStatus(PluginInfo.PluginInstanceGuid, PluginInstanceState.Initialized); // Tell main app we started
}
public void PlugginTrigger(string ConnectorGuid, object Data)
{
_MyPluggableApp.PluginStatus(AvailablePlugins.PluginInfo.PluginInstanceGuid, PluginInstanceState.Running_Busy); // Tell main app we're busy
// Run the code that actually provides the functionality of this plugin
_MyPluggableApp.PluginStatus(AvailablePlugins.PluginInfo.PluginInstanceGuid, PluginInstanceState.Running_Idle); // Tell main app we're idle
}
// and so on ...
}
And the main application:
public partial class MainWindow : IMyPluggableApp
{
[ImportMany(typeof(IPluginExport))]
IPluginExport[] _availablePlugins;
public void PluginStatus(string PluginInstanceGuid, PluginInstanceState PluginInstanceState)
{
// Code for setting status in GUI
}
public void DataReceiver(string PluginInstanceGuid, string ConnectorGuid, object Data)
{
ConnectorInfo connector_source = GetConnectorInfo(ConnectorGuid);
PluginInfo plugin_source = GetPluginInfo_ByPluginInstanceGuid(PluginInstanceGuid);
ConnectorInstanceInfo connector_destination = (from i in _project.PluginInstances
from y in i.ConnectedConnectors
where i.PluginInstanceGuid == PluginInstanceGuid
&& y.ConnectedFromOutput_ConnectorGuid == ConnectorGuid
select y).FirstOrDefault();
_availablePlugins.Where(xx => xx.PluginInfo.PluginInstanceGuid == connector_destination.ConnectedToInput_PluginInstanceGuid).First().PlugginTrigger(ConnectorGuid, Data);
}
public void Logg(string PluginInstanceGuid, LoggMessageType MessageType, string Message)
{
// Logg stuff
}
}
It's the DataReceiver function in the main app thats receives the data, looks what plugin should have it, and then sends it (via PlugginTrigger function).
A couple of observations:
Fire and forget is a requirement of the host so not something the plug-in implementations should have to worry about.
I don't think (please correct me if I am wrong) the CLR supports calling methods in a "fire-and-forget"-ful way within the same AppDomain. If your plug-ins were loaded in to separate processes, and you were communicating with them using WCF then you could simply set the IsOneWay property on your OperationContractAttribute.
The second point suggests one solution, which seems slight overkill for your situation - but let us mention it anyway. Your plug-ins could host in-process WCF services, and all the communication between the WPF application and the plug-ins could be done through the WCF service proxies. However, this comes with a configuration nightmare and is really opening a can of worms to a whole bunch of other issues you would have to solve.
Let us start with a simple example of the initial problem, and attempt to solve it from there. Here is the code for Console application with a plug-in:
public class Program
{
private static void Main(string[] args)
{
var host = new CompositionHost();
new CompositionContainer(new AssemblyCatalog(typeof(Plugin).Assembly)).ComposeParts(host);
var plugin = host.Plugin;
plugin.Method();
Console.ReadLine();
}
private class CompositionHost: IPartImportsSatisfiedNotification
{
[Import(typeof (IPlugin))] private IPlugin _plugin;
public IPlugin Plugin { get; private set; }
public void OnImportsSatisfied()
{
Plugin = _plugin;
}
}
}
public interface IPlugin
{
void Method();
}
[Export(typeof(IPlugin))]
public class Plugin : IPlugin
{
public void Method()
{
//Method Blocks
Thread.Sleep(5000);
}
}
The problem is the call to plugin.Method() is blocking. To solve this, we change the interface that is exposed to the Console application to the following:
public interface IAsyncPlugin
{
Task Method();
}
A call to an implementation of this interface will not block. The only thing we need to change is the CompositionHost class:
private class CompositionHost: IPartImportsSatisfiedNotification
{
[Import(typeof (IPlugin))] private IPlugin _plugin;
public IAsyncPlugin Plugin { get; private set; }
public void OnImportsSatisfied()
{
Plugin = new AsyncPlugin(_plugin);
}
private sealed class AsyncPlugin : IAsyncPlugin
{
private readonly IPlugin _plugin;
public AsyncPlugin(IPlugin plugin)
{
_plugin = plugin;
}
public Task Method()
{
return Task.Factory.StartNew(() => _plugin.Method());
}
}
}
}
Obviously this is a very simple example, and the implementation may have to vary slightly when applying it to your WPF scenario - but the general concept should still work.

WiX Votive Managed Custom Action cannot be referenced by other managed code in the same solution?

Question:
Is it possible to reference public static methods held within the CustomAction class, Votive generates for creating C# managed Custom Actions, from other libraries within the same solution?
I'm having trouble getting a reference to the class and method inside my C# library for the C# Custom Action when trying to create a test bed for the CA.
namespace TestInstaller.InstallCA
{
public class CustomActions
{
[CustomAction]
public static ActionResult InstallUIStart(Session session)
{
//Stuff
return Begin(<Constructed DataClass>);
}
public static ActionResult Begin(DataClass dc)
{
//Stuff I want to test
}
}
}
...
namespace TestInstaller.InstallerTest
{
static class Program
{
Static void Main()
{
//Stuff
//This line is not valid.
TestInstaller.InstallCA.CustomActions.Begin(<Constructed DataClass>);
}
}
}
Despite me adding a reference to InstallCA I cannot add a using statement for TestInstaller.InstallCA or InstallCA, and the compile time error only suggests adding a reference, which I have done.
Is this anything to do with Votive protecting its DLLs somehow?

Categories

Resources