Why does 'InputField' not contain a definition for 'text'? - authentication

I'm currently working on a Unity project for a college assignment, and I'm currently trying to connect a login/registration through PlayFab into a teammate's main menu for the game.
I've connected the PlayFabManager.cs script to the Input Fields for the email and password in the Unity editor, and something about my InputFields.cs file is preventing me from making any more progress.
I had to change the passwordInput and emailInput variables to TMP_InputField variables to achieve this, but now I am getting a compilation error in my project that says the following:
Assets\Scripts\InputField.cs(13,24): error CS1061: 'InputField' does not contain a definition for 'text' and no accessible extension method 'text' accepting a first argument of type 'InputField' could be found (are you missing a using directive or an assembly reference?)
Most places I look have people not including the "using UnityEngine.UI;" header at the top of the file, but that's included in my InputField.cs file.
Here's the code for my InputField.cs file:
using UnityEngine;
using System.Collections;
using UnityEngine.UI; // Required when Using UI elements.
public class InputField : MonoBehaviour
{
public InputField mainInputField;
public void Start()
{
mainInputField.text = "Enter text here...";
}
}
Here's the code for my PlayFabManager.cs file:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using PlayFab;
using PlayFab.ClientModels;
using Newtonsoft.Json;
using UnityEngine.UI;
using TMPro; // Needed for login input fields
public class PlayFabManager : MonoBehaviour
{
[Header("UI)")]
public Text messageText;
public TMP_InputField emailInput;
public TMP_InputField passwordInput;
// Register/Login/ResetPassword
public void RegisterButton() {
var request = new RegisterPlayFabUserRequest {
Email = emailInput.text,
Password = passwordInput.text,
RequireBothUsernameAndEmail = false
};
PlayFabClientAPI.RegisterPlayFabUser(request, OnRegisterSuccess, OnError);
}
void OnRegisterSuccess(RegisterPlayFabUserResult result) {
messageText.text = "Registered and Logged in";
}
public void LoginButton() {
}
// Start is called before the first frame update
void Start() {
Login();
}
// Update is called once per frame
void Login() {
var request = new LoginWithCustomIDRequest {
CustomId = SystemInfo.deviceUniqueIdentifier,
CreateAccount = true
};
PlayFabClientAPI.LoginWithCustomID(request, OnSuccess, OnError);
}
void OnSuccess(LoginResult result) {
Debug.Log("Successful login/account create.");
}
void OnError(PlayFabError error) {
Debug.Log("Error while loggin in/creating account.");
Debug.Log(error.GenerateErrorReport());
}
}
I would just remove the InputField.cs class as it fixes my errors, but it changes the functionality of the following code that my teammate has contributed:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class MenuControl : MonoBehaviour
{
public string newGameLevel;
public void NewUser() {
SceneManager.LoadScene(newGameLevel);
}
public void ExitButton() {
Application.Quit();
}
}
Any help would be much appreciated!

Wanted to provide the solution in case this happens to anyone in the future:
I solved the problem by changing the
public InputField mainInputField;
into an input variable that could receive the TMP_Imput like so: public TMPro.TMP_InputField mainInputField;

Related

BeforeScenario and AfterScenario hooks not working in specflow

I have the following code in my SeleniumSteps.cs code
I am trying to get the AfterScenario to fire on debugging these tests
using PrivateDomain;
using Machine.Specifications;
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;
using System;
using System.Collections.Generic;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using TechTalk.SpecFlow;
namespace Functional.Steps
{
public class SeleniumSteps : PrivateDomain.Steps.SeleniumSteps
{
#region Hooks
[BeforeScenario]
public void Before()
{
// before
}
[AfterTestRun, Scope(Tag = null)]
public new static void AfterTestRun()
{
// after testrun
}
[AfterScenario]
public void AfterScenarioErrorScreenshot()
{
// after scenario
}
#endregion
}
}
using OpenQA.Selenium;
using TechTalk.SpecFlow;
namespace PrivateDomain.Steps
{
[Binding]
[Scope(Tag = "Selenium")]
public class SeleniumSteps
{
protected static IWebDriver webDriver;
public SeleniumSteps();
public virtual IWebDriver WebDriver { get; }
[AfterTestRun]
[Scope(Tag = null)]
public static void AfterTestRun();
[AfterScenarioAttribute(new[] { })]
public virtual void AfterScenario();
}
}
My feature file looks like this:
(Details removed)
#Customer_Portal
Feature: Account Management - Registration
In order to create an account
As a customer
I want to register my details with the application
Scenario: Register
# Registration Form
When I navigate to "/Customer/Account/Register"
// more code...
Scenario: Required Fields
// more code...
Scenario: Invalid Contact Details
// more code...
Scenario: Insufficient Password Strength
// more code...
Scenario: Password Mismatch
// more code...
Scenario: Already Registered
// more code...
Scenario: Invalid Activation
// more code...
Scenario: Already Activated
// more code...
When I debug a test, I can see the debugger hitting the AfterTestRun portion.
However, neither the BeforeScenario or the AfterScenario are being exercised.
Can someone tell me what I'm doing wrong?
First, as Sandesh noted in his answer, you are missing [Binding] attribute for your SeleniumSteps subclass. It's not enough to have [Binding] only in base class, you must apply it to every class where are your hook methods or step definitions (bindings), because that is the way how specflow is searching for hooks and bindings under the hood. It is like scope identifier. If you miss to place [Binding] attribute to class, specflow will not search for potential hook methods or bindings in that class. Link on documentation: https://specflow.org/documentation/Hooks/
This link can be useful also. Check answer given by RunOfTheShipe: Specflow test step inheritance causes "Ambiguous step definitions"
You have missed [Binding] attribute in your SeleniumSteps
namespace Functional.Steps
{
[Binding]
public class SeleniumSteps : PrivateDomain.Steps.SeleniumSteps
{
#region Hooks
[BeforeScenario]
public void Before()
{
// before
}
}
}

Where to put and how to read from manually created DB file using Xamarin forms?

I created questions.db file using DB Browser.
Here it is: My lovely .db file
I want to add it to Xamarin.Forms solution and read data from it. (This is going to be quiz app)
That sounds pretty simple, right, but I'm stuck googling for hours. Most answers just link to this https://learn.microsoft.com/en-us/xamarin/xamarin-forms/data-cloud/data/databases
Which explains nothing about the manually created database file, where to put it etc.
EDIT: this is what I'm trying to achieve: https://arteksoftware.com/deploying-a-database-file-with-a-xamarin-forms-app/
Sadly, the guide is outdated and many things of it doesn't work.
So where do I put my .db file? In MyApp.Android Assets and Resources for MyApp.iOS? If so, how do I get DBpath string then for new connection?
_database = new SQLiteAsyncConnection(dbPath);
If what you want to do is:
Add a pre existing database to your project and load that database to be used by your App then keep on reading.
Short Answer
You need to add your database file to a specific folder in the paltform project (Assets in Android, in iOS you can simply create a folder and put the file there) and use DependencyService to access it. Copy the database file to somewhere in your device (App data folder or InternalStorage or watever is allowed on each platform) and use that final path in the SQLite constructor. From now on, you can simply use that SQLite connection as any other to perform CRUD operation on your Database.
Long Answer
I will now describe how to achieve this step by step from creating a new Xamarin.Forms project to reading data from the preloaded database.
Note: the follwoing solution will only cover the Android part of the CrossPlatform solution. Extending this to iOS should be no problem.
Disclaimer: The code presented next should just be taken as a guideline and by no means I suggest that is proved or production like.
0. Getting project ready:
Create a new Xamarin.Forms project (on my case i use Visual Studio v. 16.3.8 and the new project has Xamarin.Forms 4.2 installed)
Then, first of all, install sqlite nuget package in ALL your projects:
1. Prepare your Database
In App.xaml.cs file
// Create db static property to perform the
// Database calls from around the project
public static Database db { get; set; }
public App()
{
InitializeComponent();
MainPage = new MainPage();
}
Create a new class file and name it Database.cs. There you open the database connection.
public class Database
{
// Create a SQLiteAsyncConnection property to be accessed
// publicly thru your App.
public SQLiteAsyncConnection DBInstance { get; set; }
public Database(String databasePath)
{
DBInstance = new SQLiteAsyncConnection(databasePath);
}
private async Task<string> GetDatabaseFilePath()
{
return await DependencyService.Get<IPathFinder>().GetDBPath();
}
}
So far so good, but... What should actually be the path of your preloaded database?
Well, that is the next part.
2. Load pre-existent database to your project and get a path to it (Android)
So the big question is where to store your pre-existent database in the project.
One option is to add it as an Asset. To implement this approach, do the following:
2.1 Add database file to Assets folder in Android project
Now we want to access that database. To do so, follow the next steps:
2.2 Create an Interface IPathFinder in your App project
And there define a single member GetDBPath()
public interface IPathFinder
{
Task<String> GetDBPath();
}
Now, in your Android project create a class file PathFinder.cs to implement this interface
and implement the method (Note the Dependency Attribute above the namespace!)
using System;
using SysIO = System.IO;
using System.Threading.Tasks;
using Java.IO;
using Xamarin.Forms;
using TestDB.Droid;
[assembly: Dependency(typeof(PathFinder))]
namespace TestDB.Droid
{
public class PathFinder : IPathFinder
{
public async Task<string> GetDBPath()
{
String dbPath = String.Empty;
if (await PermissonManager.GetPermission(PermissonManager.PermissionsIdentifier.Storage))
{
String systemPath = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.RootDirectory.Path).Path;
String tempFolderPath = SysIO::Path.Combine(systemPath, "MytestDBFolder");
if (!SysIO::File.Exists(tempFolderPath))
{
new File(tempFolderPath).Mkdirs();
}
dbPath = SysIO::Path.Combine(tempFolderPath, "test.db");
if (!SysIO::File.Exists(dbPath))
{
Byte[] dbArray;
using (var memoryStream = new SysIO::MemoryStream())
{
var dbAsset = MainActivity.assets.Open("test.db");
dbAsset.CopyTo(memoryStream);
dbArray = memoryStream.ToArray();
}
SysIO.File.WriteAllBytes(dbPath, dbArray);
}
}
return dbPath;
}
}
}
In the GetDBPath() method, the first to note is the GetPermission method. This is needed since Android API 23 in order to manage the App permissions.
Create a file called PermissonManager in your Android project
And add the code below
using System;
using System.Threading.Tasks;
using Android;
using Android.App;
using Android.Content.PM;
using Android.OS;
using Android.Support.V4.App;
namespace TestDB.Droid
{
public class PermissonManager
{
public enum PermissionsIdentifier
{
Storage // Here you can add more identifiers.
}
private static String[] GetPermissionsRequired(PermissionsIdentifier identifier)
{
String[] permissions = null;
if (identifier == PermissionsIdentifier.Storage)
permissions = PermissionExternalStorage;
return permissions;
}
private static Int32 GetRequestId(PermissionsIdentifier identifier)
{
Int32 requestId = -1;
if (identifier == PermissionsIdentifier.Storage)
requestId = ExternalStorageRequestId;
return requestId;
}
public static TaskCompletionSource<Boolean> PermissionTCS;
public static readonly String[] PermissionExternalStorage = new String[] { Manifest.Permission.ReadExternalStorage, Manifest.Permission.WriteExternalStorage };
public const Int32 ExternalStorageRequestId = 2;
public static async Task<Boolean> GetPermission(PermissionsIdentifier identifier)
{
Boolean isPermitted = false;
if ((Int32)Build.VERSION.SdkInt < 23)
isPermitted = true;
else
isPermitted = await GetPermissionOnSdk23OrAbove(GetPermissionsRequired(identifier), GetRequestId(identifier));
return isPermitted;
}
private static Task<Boolean> GetPermissionOnSdk23OrAbove(String[] permissions, Int32 requestId)
{
PermissionTCS = new TaskCompletionSource<Boolean>();
if (MainApplication.CurrentContext.CheckSelfPermission(permissions[0]) == (Int32)Permission.Granted)
PermissionTCS.SetResult(true);
else
ActivityCompat.RequestPermissions((Activity)MainApplication.CurrentContext, permissions, requestId);
return PermissionTCS.Task;
}
public static void OnRequestPermissionsResult(Permission[] grantResults)
{
PermissionTCS.SetResult(grantResults[0] == Permission.Granted);
}
}
}
In that class you note the presence of MainApplication, which provides the CurrentContext. You will also have to add that class file
and there add the following code
using System;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
namespace DemoDB.Droid
{
[Application]
public partial class MainApplication : Application, Application.IActivityLifecycleCallbacks
{
private static Context _currentContext = Application.Context;
internal static Context CurrentContext
{
get => _currentContext;
private set
{
_currentContext = value;
}
}
internal static String FileProviderAuthority
{
get => MainApplication.CurrentContext.ApplicationContext.PackageName + ".fileprovider";
}
public MainApplication(IntPtr handle, JniHandleOwnership transfer) : base(handle, transfer)
{
}
public override void OnCreate()
{
base.OnCreate();
RegisterActivityLifecycleCallbacks(this);
}
public override void OnTerminate()
{
base.OnTerminate();
UnregisterActivityLifecycleCallbacks(this);
}
public void OnActivityCreated(Activity activity, Bundle savedInstanceState)
{
CurrentContext = activity;
}
public void OnActivityDestroyed(Activity activity)
{
}
public void OnActivityPaused(Activity activity)
{
}
public void OnActivityResumed(Activity activity)
{
CurrentContext = activity;
}
public void OnActivitySaveInstanceState(Activity activity, Bundle outState)
{
}
public void OnActivityStarted(Activity activity)
{
CurrentContext = activity;
}
public void OnActivityStopped(Activity activity)
{
}
}
}
Then your PermissonManager is almost ready. Now you just have to override OnRequestPermissionsResult in the MainActivity file
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
PermissonManager.OnRequestPermissionsResult(grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
Getting back to the GetPath() method, you see a mysterious MainActivity.assets property call. This has to be created in the MainActivity as follows
public static AssetManager assets;
protected override void OnCreate(Bundle savedInstanceState)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
assets = this.Assets;
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App());
}
Almost ready! Now you just call your database.
3. Use your database!
From the OnAppearing of the Main page, make a simple call to the database, to create it and access it.
protected override async void OnAppearing()
{
String databasePath = await Database.GetDatabaseFilePath();
App.db = new Database(databasePath);
var table = await App.db.DBInstance.CreateTableAsync<Category>();
// here Category is a class that models the objects
// present in my pre-existent database
List<Category> categories = new List<Category>();
categories = await App.db.DBInstance.Table<Category>().ToListAsync();
base.OnAppearing();
}
And that is it.
I hope this is helpful :P

How to get first or guardian actor in akka.net?

Edit : Executive summary: Where the bleep is 'Sys' defined? I see it in Akka.net code all over the internet, but my build is not finding it. Who or what do I have to import, use, link, do, bribe or kill?
Should be screamingly easy. Taking first steps in Akka.net, the sample does not build. This was copied from the [Getting Started example][1]
[1]: https://getakka.net/articles/intro/tutorial-1.html . It does not build, because 'Sys' is not defined. This obviously elementary step is nowhere described on their site, and I've given up on tweak-n-try.
Here is all of the code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyAkka
{
class Program
{
public class PrintMyActorRefActor : UntypedActor
{
protected override void OnReceive(object message)
{
switch (message)
{
case "printit":
IActorRef secondRef = Context.ActorOf(Props.Empty, "second-actor");
Console.WriteLine($"Second: {secondRef}");
break;
}
}
}
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
var firstRef = Sys.ActorOf(Props.Create<PrintMyActorRefActor>(), "first-actor");
Console.WriteLine($"First: {firstRef}");
firstRef.Tell("printit", ActorRefs.NoSender);
Console.ReadKey();
}
}
}
Here is a working version of your code:
using System;
using Akka.Actor;
namespace SysInAkkaNet
{
class Program
{
public class PrintMyActorRefActor : UntypedActor
{
protected override void OnReceive(object message)
{
switch (message)
{
case "printit":
IActorRef secondRef = Context.ActorOf(Props.Empty, "second-actor");
Console.WriteLine($"Second: {secondRef}");
break;
}
}
}
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
using (var actorSystem = ActorSystem.Create("MyActorSystem"))
{
var firstRef = actorSystem.ActorOf(Props.Create<PrintMyActorRefActor>(), "first-actor");
Console.WriteLine($"First: {firstRef}");
firstRef.Tell("printit", ActorRefs.NoSender);
Console.ReadKey();
}
}
}
}
You need to create an actor system to put your actors in. And you need to add a reference to the Akka NuGet package, and a corresponding using Akka.Actor; statement.
I know that the Akka.TestKit has a property Sys, which gives you a reference to the actor system that is created for a given test.
Apart from that, I am not able to answer why the documentation you are referring to shows these "Sys.ActorOf(...)" examples like that (with a capital S), indicating that it is a (possibly built-in) property, so I kind of understand your confusion there.

Ninject Decorator not being used

What I am trying to do is wrap a decorator around a command using the following code.
public interface ICommand
{
}
public interface ICommand<T> : ICommand where T : class
{
void Execute(T args);
}
public class TransactionalCommand<T> : ICommand<T>
where T : class
{
private readonly ICommand<T> command;
public TransactionalCommand(ICommand<T> command)
{
this.command = command;
}
public void Execute(T args)
{
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
{
this.command.Execute(args);
scope.Complete();
}
}
}
Here is how I am invoking the resolve but i only get back my ChangePasswordCommand without the decoratoration. (Actually it wont event compile on the second Bind)
The ultimate goal is to have this auto-register all my types using this decorator. Any help would be great!
Bind<ChangePasswordCommand>().To<ChangePasswordCommand>()
.WhenInjectedInto<TransactionalCommand<ChangePasswordArgs>>();
Bind<ChangePasswordCommand>().To<TransactionalCommand<ChangePasswordArgs>>()
.InTransientScope();
var command = kernel.Get<ChangePasswordCommand>();
You were pretty close. However: when you want to use a decorator you need the decorator to implement the same interface as the command. That's the case here, but you'll also need to resolve that interface (and bind it, too). So here's how it works:
kernel.Bind<ICommand<ChangePasswordArgs>>().To<ChangePasswordCommand>()
.WhenInjectedInto<TransactionalCommand<ChangePasswordArgs>>();
kernel.Bind<ICommand<ChangePasswordArgs>>().To<TransactionalCommand<ChangePasswordArgs>>()
.InTransientScope();
var command = kernel.Get<ICommand<ChangePasswordArgs>>();

Instantiate using Windsor's factory

Below's code is working fine, and successfully create an instance for class DummyComponnent.
But the problem arises when i had changed the factory method name CreatDummyComponnent()
to GetDummyComponnent() or anything else except Creat as the beginning of method name, say AnyThingComponent throws an exception. is there any specify naming rule for factory methods ?
using System;
using Castle.Facilities.TypedFactory;
using Castle.MicroKernel.Registration;
using Castle.Windsor;
namespace AsFactoryImplementation
{
public interface IDummyComponnentFactory
{
IDummyComponnent CreatDummyComponnent();
// void Relese(IDummyComponnent factory);
}
public interface IDummyComponnent
{
void Show();
}
public class DummyComponnent:IDummyComponnent
{
public DummyComponnent()
{
Console.WriteLine("we are working here");
}
public void Show()
{
Console.WriteLine("just testing this for better performance");
}
}
class Program
{
static void Main(string[] args)
{
var container = new WindsorContainer();
container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<IDummyComponnent>().ImplementedBy<DummyComponnent>().Named("FirstConnection"),
Component.For<IDummyComponnentFactory>().AsFactory());
var val = container.Resolve<IDummyComponnentFactory>();
var iDummy = val.CreatDummyComponnent();
iDummy.Show();
Console.WriteLine("OK its done ");
Console.ReadLine();
}
}
}
You should be able to use anything for starting the method names on the Factory, except for starting with Get.
If you start with Get it will try to resolve the component by name instead of by interface.
So what would work in your example is:
var iDummy = val.GetFirstConnection();
Good luck,
Marwijn.