Xamarin DependencyService - c#

I followed other questions in stack overflow and made sure my register in the assembly registers the android implementation and not the base interface and also that all classes are public. Anyhow I still get the System.MissingMethodException: 'Default constructor not found for type Foodies.VisualEffects.IStatusBarColor'message.
I declare my base interface in the common project at Foodies/Views/VisualEffects/iStatusBarColor.cs, like this:
namespace Foodies.Views.VisualEffects
{
public interface IStatusBarColor
{
void MakeMe(string color);
}
}
Then in my android project I add StatusBarColor_Android, looking like:
using Android.OS;
using Foodies.Droid;
using Foodies.Views.VisualEffects;
using Xamarin.Forms.Platform.Android;
[assembly: Xamarin.Forms.Dependency(typeof(StatusBarColor_Android))]
namespace Foodies.Droid
{
public class StatusBarColor_Android : IStatusBarColor
{
public void MakeMe(string color)
{
if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop)
{
var c = MainActivity.context as FormsAppCompatActivity;
c?.RunOnUiThread(() => c.Window.SetStatusBarColor(Android.Graphics.Color.ParseColor(color)));
}
}
}
}
and them from my main page I call:
var dp = DependencyService.Get<IStatusBarColor>();
dp?.MakeMe(Color.Blue.ToHex());
And there, i the DependencyService.Get I do get the System.MissingMethodException: 'Default constructor not found for type Foodies.VisualEffects.IStatusBarColor
This is my android project settings
Im new to Xamarin, could someone help me finding the error ??

Found out in addition to all of this, in the MainActivity, in the OnCreate I had
DependencyService.Register<IStatusBarColor>();
Just remove this sentence and it works nice.
Additionally, changing the registered class too StatusBarColor_Android, and not the base interface also works. I found it just cleaner to remove the whole thing and let the [assembly...] do the job

The namespace in the code above is confusing,as you said
I declare my base interface in the common project at
Foodies/Views/iStatusBarColor.cs
Normally if you don't customize namepace, it should be:
namespace Foodies.Views
{
public interface IStatusBarColor
{
void MakeMe(string color);
}
}
and in you Android project,why you have two different reference using Foodies.Droid; and using Foodies.VisualEffects.Droid;,and you didn't reference the namepace Foodies.Views when you implement IStatusBarColor
Try to change like :
using Foodies.Droid;
using Foodies.Views;
using Android.OS;
using Xamarin.Forms.Platform.Android;
[assembly: Xamarin.Forms.Dependency(typeof(StatusBarColor_Android))]
namespace Foodies.Droid
{
public class StatusBarColor_Android : IStatusBarColor
{
public void MakeMe(string color)
{
if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop)
{
var c = MainActivity.context as FormsAppCompatActivity;
c?.RunOnUiThread(() => c.Window.SetStatusBarColor(Android.Graphics.Color.ParseColor(color)));
}
}
}
}
Update :
The cause of this problem is the wrong registration method.There are two ways to register.
1.Register in your implementation class directly,like the codes above
using [assembly: Xamarin.Forms.Dependency(typeof(StatusBarColor_Android))]
2.call DependencyService.Register<StatusBarColor_Android >(); in your MainActivity OnCreate method.(Note:here you should use the class name which you implement the interface,not the name of interface).

Related

Using namespace in Unity hides functionality

Using Unity 5.4 beta with Hololens, setting a class within a namespace disables some UnityEngine functionality.
If I declare a class, it all works fine. If I wrap it inside a namespace, classes don't see each other, even within the same namespace or with the using addition.
Making a class MonoBehaviour, I can drag and drop it onto a game object, if I wrap that class inside a namespace, Unity complains that it is not a MB or it has issue so it cannot be dragged.
Does anyone have similar issue? Just asking before reporting bugs since 5.4 is still beta.
Classes don't see each other because you are not importing them or accessing them through their namespace. To access anything in a namespace, you must import the namespace or call the namespace followed by the class name. Check below for both examples.
Class with namespace:
namespace MyANameSpace
{
public class A
{
}
}
In order to see class A, you have to import it with the using keyword.
using MyANameSpace;
public class B : MonoBehaviour
{
A a;
// Use this for initialization
void Start()
{
a = new A();
}
}
Another method is to access them directly through the namespace.
public class B : MonoBehaviour
{
MyANameSpace.A a;
// Use this for initialization
void Start()
{
a = new MyANameSpace.A();
}
}
If this does not solve your problem, then you have to post your code. That's likely not a bug.
I managed to figure out what I think is happening. Here is what I had:
namespace Company.Hololens
{
public enum GazeState
{
None = -1, NoHit, Hit
}
public class CursorEventArg : EventArgs
{
}
public class CursorController : Singleton<CursorController>
{
}
}
and it seems as if Unity does not like the order of class declaration. Pushing the EventArg down to the end of the script and it goes fine.
Not sure if this should be considered a bug, I have never seen any mention of class declaration order. Declaring an interface on top is fine though.

How do I register classes by both interface and namespace with Windsor?

I'm trying to use Castle.Windsor (3.2.0.0) convention based registration, but can't seem to figure out how to register classes implementing a particular interface only in a particular namespace.
e.g. what I really want to be able to write is something like this :
container.Register(Classes.FromThisAssembly()
.InNamespace("MyApp.EventHandlers")
.BasedOn(typeof(IHandlesEvent<>))
.WithServiceAllInterfaces()
But I get a warning that seems to imply what this will really do is register everything in the EventHandlers namespace and then everything in the current assembly that implements IHandlesEvent<>.
If I run the application this does indeed seem to be what happens. I don't want everything that implements that interface to be registered (for example, some of the implementing classes are Sagas, which need to be manually tracked) and I don't really want everything in that namespace registered.
I really don't want to register the event handlers individually, but I can't see from the Windsor documentation how to do what I need by convention. Is it possible?
I'm surprised too, but I could observe the behavior on Castle 3.2. BasedOn pushed a warning saying that it would reinitialize the registration: here is my sample code:
namespace WindsorTest
{
public interface IHandlesEvent {}
public interface IDontWantToBeRegistered {}
namespace Select
{
public class SelectClass : IHandlesEvent { }
public class DontRegisterMe : IDontWantToBeRegistered { }
}
namespace DontSelect
{
public class DontSelectClass: IHandlesEvent {}
}
internal class Program
{
private static void Main(string[] args)
{
var container = new WindsorContainer();
container.Register(Classes.FromThisAssembly()
.InNamespace("WindsorTest.Select")
.BasedOn<IHandlesEvent>()
.WithServiceAllInterfaces()
);
foreach (var handler in container.ResolveAll<IHandlesEvent>())
{
Console.WriteLine(handler.GetType().Name);
}
foreach (var handler in container.ResolveAll<IDontWantToBeRegistered>())
{
Console.WriteLine(handler.GetType().Name);
}
Console.ReadLine();
}
}
}
It outputs DontSelectClass when ran.
However I found a way to start with the base class for your registration and refine it with the namespace afterwards. Just use:
container.Register(Classes.FromThisAssembly()
.BasedOn<IHandlesEvent>()
.If(t => t.Namespace == "WindsorTest.Select")
.WithServiceAllInterfaces()
);

Interface reference problems in c#

i'm trying to learn interfaces, and got stuck on this problem..
i have 3 libraries..
calculateLibrary
arguments.cs ,
calculator.cs ,
calculatorMain.cs ,
commandTypes.cs ,
inputParser.cs ,
setInput.cs
InterfacesLibrary
Iarguments.cs ,
Icalculator.cs ,
IcalculatorMain.cs ,
IinputParser.cs ,
IsetInput.cs
typescript(web)
index.aspx
so my problem is some of my interfaces methods is not working, or it says "the type or namespace name 'commandTypes cound not be found(are you missing a using directive or an assembly reference?)
the commandTypes in my IinputParser is what the error is pointing.
code for my interface
namespace calculateLibrary
{
public interface IinputParser
{
commandTypes parseCommand(string command);
}
}
and code for the method that inherits the interface
namespace calculateLibrary
{
public class inputParser : IinputParser
{
public commandTypes parseCommand(string command)
{
return ((commandTypes)Enum.Parse(typeof(commandTypes), command));
}
}
}
this is the code for my commandType class
namespace calculateLibrary
{
public enum commandTypes
{
add,
sub,
mul,
div
}
}
i think the problem is not about reference..because some of my Interfaces is working fine..i mean there is no error.. i saw some related post but those didn't help me.
thanks.
Since both IinputParser and inputParser need to use commandTypes, I would suggest moving commandTypes.cs to InterfacesLibrary project to avoid circular reference. The namespace needs to be changed as well. Here's what the code of commandTypes should look like after being moved to InterfacesLibrary project:
namespace InterfacesLibrary
{
public enum commandTypes
{
add,
sub,
mul,
div
}
}
The code of IinputParser should have InterfacesLibrary as the namespace
namespace InterfacesLibrary
{
public interface IinputParser
{
commandTypes parseCommand(string command);
}
}
and here's the code of inputParser class:
using InterfacesLibrary;
namespace calculateLibrary
{
public class inputParser : IinputParser
{
public commandTypes parseCommand(string command)
{
return ((commandTypes)Enum.Parse(typeof(commandTypes), command));
}
}
}
It seems the problem is Circular Reference as you have declared commandTypes in your CalculateLibrary and use it in IinputParser Interface in public commandTypes parseCommand(string command) which is in InterfaceLibrary, then your want to reference InterfaceLibrary from CalculateLibrary.
CommandTypes (CalculateLibrary) -> IinputParser (InterfaceLibrary) -> inputParser (CalculateLibrary)
you should either put these classes used by your Interfaces in InterfaceLibrary, or declare them in a lower level library as somthing like Core and then reference it from both InterfaceLibrary and CalculateLibrary

Default namespace in C#

I want to know which is the default namespace of class defined by the programmer,if not specify any?
Let, take the case of Java.
In Java, if Programmer is not specify any package then default package is the java.lang
Same way i want to know about default namespace of C# classes.
global is the default namespace.
Example:
class GlobalClass {
}
namespace MyNamespace {
class NameSpaceClass {
public NameSpaceClass() {
var globalObj = new global::GlobalClass();
}
}
}
MSDN Link: http://msdn.microsoft.com/en-us/library/cc713620.aspx

C# subclass while maintaining name. Deep voodoo?

I have a dll that I'm working with, it contains a class foo.Launch. I want to create another dll that subclasses Launch. The problem is that the class name must be identical. This is used as a plugin into another piece of software and the foo.Launch class is what it looks foe to launch the plugin.
I've tried:
namespace foo
{
public class Launch : global::foo.Launch
{
}
}
and
using otherfoo = foo;
namespace foo
{
public class Launch : otherfoo.Launch
{
}
}
I've also tried specifying an alias in the reference properties and using that alias in my code instead of global, that also didn't work.
Neither of those methods work. Is there a way I can specify the name of the dll to look in within the using statement?
You'll need to alias the original assembly and use an extern alias to reference the original assembly within the new one. Here's an example of the use of the alias.
extern alias LauncherOriginal;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace foo
{
public class Launcher : LauncherOriginal.foo.Launcher
{
...
}
}
Here's a walkthrough that explains how to implement that.
Also, you'd mentioned that you tried to use an alias before and encountered problems but you didn't say what they were, so if this won't work then please mention what went wrong.
as Chris said, you can use an alias on your original assembly.
If you can't you that, then you might be able to cheat by using a 3rd assembly
Assembly1.dll (your original)
namespace foo {
public class Launch {}
}
Assembly2.dll (dummy)
namespace othernamespace {
public abstract class Dummy: foo.Launch {}
}
Assembly3.dll (your plugin)
namespace foo{
public class Launch: othernamespace.Dummy{}
}
I'm not even proud of this!
Class name can be identical if it's defined in another namespace, but it boggles the mind why anybody would want to do that to themselves.
Maybe you need to use extern aliases.
For example:
//in file foolaunch.cs
using System;
namespace Foo
{
public class Launch
{
protected void Method1()
{
Console.WriteLine("Hello from Foo.Launch.Method1");
}
}
}
// csc /target:library /out:FooLaunch.dll foolaunch.cs
//now subclassing foo.Launch
//in file subfoolaunch.cs
namespace Foo
{
extern alias F1;
public class Launch : F1.Foo.Launch
{
public void Method3()
{
Method1();
}
}
}
// csc /target:library /r:F1=foolaunch.dll /out:SubFooLaunch.dll subfoolaunch.cs
// using
// in file program.cs
namespace ConsoleApplication
{
extern alias F2;
class Program
{
static void Main(string[] args)
{
var launch = new F2.Foo.Launch();
launch.Method3();
}
}
}
// csc /r:FooLaunch.dll /r:F2=SubFooLaunch.dll program.cs

Categories

Resources