Xamarin Realm - when to close Realm - xamarin

I have a Shared Project where I have changed the database to Realm instead of SQLite.
My problem is, if I close the Realm in my DatabaseManager, the result is removed. Therefore i have created a static singelton instance of the Realm, which all my DatabaseManager use. Now my app crash after short time on memory, and if i remove all my database-functions, it works.
I create my Realm-instance here:
public class RealmDatabase
{
private Realm mRealmDB;
public Realm RealmDB
{
get
{
if (mRealmDB == null || mRealmDB.IsClosed)
{
SetRealm ();
}
return mRealmDB;
}
}
static RealmDatabase cCurrentInstance;
public static RealmDatabase Current
{
get
{
if (cCurrentInstance == null)
cCurrentInstance = new RealmDatabase ();
return cCurrentInstance;
}
}
public RealmDatabase ()
{
}
private void SetRealm ()
{
var config = new RealmConfiguration ("DBName.realm", true);
mRealmDB = Realm.GetInstance (config);
}
public Transaction BeginTransaction ()
{
return RealmDB.BeginWrite ();
}
}
The I have my DatabaseManagler looking like this:
public class NewFreeUserManager
{
internal Realm RealmDB = RealmDatabase.Current.RealmDB;
static NewFreeUserManager cCurrentInstance;
public static NewFreeUserManager Current
{
get
{
if (cCurrentInstance == null)
cCurrentInstance = new NewFreeUserManager ();
return cCurrentInstance;
}
}
private NewFreeUserManager ()
{
}
internal bool Save (FreeUser freeuser)
{
try
{
using (var trans = RealmDB.BeginWrite ())
{
RealmDB.RemoveAll<FreeUser> ();
var fu = RealmDB.CreateObject<FreeUser> ();
fu = freeuser;
trans.Commit ();
}
return true;
}
catch (Exception e)
{
Console.WriteLine ("FreeUser save: " + e.ToString ());
return false;
}
}
internal FreeUser Get ()
{
return RealmDB.All<FreeUser> ().FirstOrDefault ();
}
}
Can anyone help me?

there are a few issues with your current setup that prevent you from persisting objects properly.
The first and very important one is that Realm instances are not thread-safe. That is, using them as singletons is strongly discouraged, unless you are certain that you'll never access them from another thread.
The second is more subtle, but in your save method you are calling:
var fu = RealmDB.CreateObject<FreeUser>();
fu = freeuser;
What it does is, effectively, you are creating an object in the Realm, and then assigning the variable to another object. This will not assign freeuser's properties to fu, it just replaces one reference with another. What you're looking for is Realm.Manage so your code should look like this:
using (var trans = RealmDB.BeginWrite())
{
RealmDB.Manage(freeuser);
trans.Commit();
}
Once you fix the second bug, you should be able to go back and close Realm instances when you don't need them anymore.

Related

WCF Service to display on a Winform its current data

I'm making a 2-stage "reservation management" program that other Software interacts with via WCF messages. Clients can claim a reservation, and release a reservation they previously had laid claim to. I'd like all this reservation info to be viewable on a WinForm for the host.
What I'm not sure how to accomplish is getting data from the Service into my WinForm. Im still very green when it comes to WCF stuff, I followed the MSDN guide to get that skeleton, but they didnt go into much detail tying to GUIs, or having any stored info.
My Service:
namespace ReservationServiceLib
{
public class reservation
{
public string location;
public bool claimed;
public string currentHolder;
public reservation(string l)
{
location = l;
claimed = false;
currentHolder = "host";
}
}
public class ReservationService : IReservationService
{
public bool reservationManagerLocked= false;
public List<reservation> keys = new List<reservation>();
private static Mutex managerLock = new Mutex();
public bool GetAccess(string n1)
{
//get acceess lock for using the reservationManager
return true;
}
public bool ClaimReservation(string rez, string clientN)
{
//Client requests/retrieves key
if(reservationManagerLocked!=true)
{
int i = 999;
i = keys.IndexOf(keys.Find(delegate (reservation x) { return x.location == rez; }));
if((keys[i].claimed == false) && (i < 999))
{
i = 999;
keys[i].claimed = true;
keys[i].currentHolder = clientN;
return true;
}
}
return false;
}
public bool ReleaseReservation(string n1)
{
//Client relenquishes access to key
return true;
}
And my "host" Winform:
namespace ReservationManager
{
public partial class ReservationManager : Form
{
public void populateComboBox()
{
for (int x = 0; x < dataGridView_IZone.Rows.Count-1; x++)
{
//comboBox_keyNames.Items.Add(dataGridView_IZone.Rows[x].Cells[0].Value);
}
}
public IZoneManager()
{
//create Keys and add to service's store of keys
//setup GUI
InitializeComponent();
// Step 1: Create a URI to serve as the base address.
Uri baseAddress = new Uri("http://localhost:8000/ReservationServiceLib/");
CalculatorService CSs = new CalculatorService();
// Step 2: Create a ServiceHost instance.
ServiceHost selfHost = new ServiceHost(typeof(ReservationService), baseAddress);
try
{
// Step 3: Add a service endpoint.
selfHost.AddServiceEndpoint(typeof(IReservation), new WSHttpBinding(), "ReservationService");
// Step 4: Enable metadata exchange.
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
selfHost.Description.Behaviors.Add(smb);
// Step 5: Start the service.
selfHost.Open();
Console.WriteLine("The service is ready.");
}
catch (CommunicationException ce)
{
Console.WriteLine("An exception occurred: {0}", ce.Message);
selfHost.Abort();
}
}
}
}

Mocking a class with internal SDK calls using NSubstitute

First time trying to use NSubstitute.
I have the following method in my Web API.
For those who don't know Couchbase, lets say that a collection/bucket is like a DB table and a key is like a DB row.
Couchbase_internal.Collection_GET returns Task<ICouchbaseCollection>
I would like to write 2 unit tests.
One that tests the returned class when the key exist and one when it doesn't (couchbaseServiceResultClass).
I don't really understand where is the part where I control whether or not the key exist in the mocked data.
public class CouchbaseAPI : ControllerBase, ICouchbaseAPI
{
// GET /document_GET?bucketName=<bucketName>&key=<key>
[HttpGet]
[Consumes("application/x-www-form-urlencoded")]
[Produces(MediaTypeNames.Application.Json)]
public async Task<couchbaseServiceResultClass> document_GET([FromQuery, BindRequired] string bucketName, [FromQuery, BindRequired] string key)
{
var collection = await Couchbase_internal.Collection_GET(bucketName);
if (collection != null)
{
IGetResult result;
try
{
// get document
result = await collection.GetAsync(key);
}
catch (CouchbaseException ex)
{
return new ErrorHandling().handleCouchbaseException(ex);
}
couchbaseServiceResultClass decryptResult = new();
try
{
// decrypt document
decryptResult = Encryption.decryptContent(result);
}
catch (Exception ex)
{
return new ErrorHandling().handleException(ex, null);
}
// remove document if decryption failed
if (!decryptResult.DecryptSuccess)
{
try
{
await collection.RemoveAsync(key);
}
catch (CouchbaseException ex)
{
return new ErrorHandling().handleCouchbaseException(ex);
}
}
decryptResult.Message = "key retrieved successfully";
// return result
return decryptResult;
}
else
{
return new ErrorHandling().handleError("Collection / bucket was not found.");
}
}
This is what I have so far for the first test:
public class CouchbaseAPITests
{
private readonly CouchbaseAPI.Controllers.ICouchbaseAPI myClass = Substitute.For<CouchbaseAPI.Controllers.ICouchbaseAPI>();
[Fact]
public async Task document_GET_aKeyIsRetrievedSuccessfully()
{
// Arrange
string bucketName = "myBucket";
string keyName = "myKey";
couchbaseServiceResultClass resultClass = new();
resultClass.Success = true;
resultClass.Message = "key retrieved successfully";
myClass.document_GET(bucketName, keyName).Returns(resultClass);
// Act
var document = await myClass.document_GET(bucketName, keyName);
// Assert
Assert.True(document.Success);
Assert.Equal("key retrieved successfully", document.Message);
}
}
If we want to test that we are retrieving documents from the Couchbase API properly, then generally we want to use a real instance (local test setup) of that API where possible. If we are mocking this then our tests are not really telling us about whether our code is working correctly (just that our mock is working the way we want it to).
When certain APIs are difficult to use real instances for (e.g. non-deterministic code, difficult to reproduce conditions such as network errors, slow dependencies, etc), that's when it can be useful to introduce an interface for that dependency and to mock that for our test.
Here's a very rough example that doesn't quite match the code snippets posted, but hopefully will give you some ideas on how to proceed.
public interface IDataAdapter {
IEnumerable<IGetResult> Get(string key);
}
public class CouchbaseAdapter : IDataAdapter {
/* Implement interface for Couchbase */
}
public class AppApi {
private IDataAdapter data;
public AppApi(IDataAdapter data) {
this.data = data;
}
public SomeResult Lookup(string key) {
try {
var result = data.Get(key);
return Transform(Decrypt(result));
} catch (Exception ex) { /* error handling */ }
}
}
[Fact]
public void TestWhenKeyExists() {
var testAdapter = Substitute.For<IDataAdapter>();
var api = new AppApi(testAdapter);
testAdapter.Get("abc").Returns(/* some valid data */);
var result = api.Lookup("abc");
/* assert that result is decrypted/transformed as expected */
Assert.Equal(expectedResult, result);
}
[Fact]
public void TestWhenKeyDoesNotExist() {
var testAdapter = Substitute.For<IDataAdapter>();
var api = new AppApi(testAdapter);
var emptyData = new List<IGetResult>();
testAdapter.Get("abc").Returns(emptyData);
var result = api.Lookup("abc");
/* assert that result has handled error as expected */
Assert.Equal(expectedError, result);
}
Here we've introduced a IDataAdapter type that our class uses to abstract the details of which implementation we are using to get data. Our real code can use the CouchbaseAdapter implementation, but our tests can use a mocked version instead. For our tests, we can simulate what happens when the data adapter throws errors or returns specific information.
Note that we're only testing AppApi here -- we are not testing the CouchbaseAdapter implementation, only that AppApi will respond in a certain way if its IDataAdapter has certain behaviour. To test our CouchbaseAdapter we will want to use a real instance, but we don't have to worry about those details for testing our AppApi transformation and decryption code.

Initialize an xamarin view after an async method

Good evening everyone.
For some time now I have been to Xamarin. My first tests are rather conclusive. I decided to try to make a small application that retrieves information in a database via an API and then update this data via a ListView.
When I launch the application on my emulator everything works but as soon as I install the application on my phone it crashes. I thought this was because the API but I have an API that I use to check the Login / password that works correctly.
The API that returns the data reviews a lot of line about 3500/4000, can this be the reason?
So I passed the loading of the data in my viewModel in an async method but the problem now is that the view loads before the data is loaded correctly. Is there a way to get the view initialized after the data is loaded?
Below my code.
Initializing my viewModel
class ManageInventViewModel
{
public ObservableCollection<InventViewModel> InventProduct { get; set; }
public Command<InventViewModel> UpdateCommand
{
get
{
return new Command<InventViewModel>(invent =>
{
var index = invent.IndexLigneInventaire;
InventProduct.Remove(invent);
InventProduct.Insert(index, invent);
});
}
}
public Command<InventViewModel> ResetStock
{
get
{
return new Command<InventViewModel>(invent =>
{
var index = InventProduct.IndexOf(invent);
InventProduct.Remove(invent);
invent.RealStockProduct = 0;
InventProduct.Insert(index, invent);
});
}
}
public ManageInventViewModel()
{
LoadInventaire();
}
private async void LoadInventaire()
{
var listMvt = await Utils.Utils.GetListMouvementUntilDate();
var listStock = Utils.Utils.GetStockByProduct(listMvt).Take(20);
InventProduct = new ObservableCollection<InventViewModel>();
var indexLine = 0;
foreach (var stock in listStock)
{
var inventViewModel = new InventViewModel
{
LibelleProduit = stock.LibelleProduit,
PrCodeProduit = stock.PrCodeProduit,
UpCodeProduit = stock.UpCodeProduit,
RealStockProduct = stock.StockTheoProdct,
StockTheoProdct = stock.StockTheoProdct,
IndexLigneInventaire = indexLine
};
++indexLine;
InventProduct.Add(inventViewModel);
}
}
}
Initializinz my view
public partial class InventPage : ContentPage
{
public InventPage()
{
InitializeComponent();
TableInvent.ItemSelected += (sender, e) =>
{
if (TableInvent.SelectedItem != null)
{
if (TableInvent.SelectedItem is InventViewModel item)
{
PopupNavigation.Instance.PushAsync(new ChangeStockModal(item, this));
}
TableInvent.SelectedItem = null;
}
};
}
private void Reset_Stock(object sender, EventArgs e)
{
var input = sender as Button;
var inventViewModel = input?.BindingContext as InventViewModel;
var listViewModel = BindingContext as ManageInventViewModel;
listViewModel?.ResetStock.Execute(inventViewModel);
}
public void Update_Stock_List(InventViewModel dataStockUpdate)
{
var listViewModel = BindingContext as ManageInventViewModel;
listViewModel?.UpdateCommand.Execute(dataStockUpdate);
PopupNavigation.Instance.PopAsync();
}
}
Thanks
I managed to create the ActivityIndicator but I can not get my data loaded while I'm displaying the wait screen.
Regarding this issue, I don't see you useActivityIndicator from your code,maybe you didn't update your code, I think if you use useActivityIndicator , You can bind one property to ActivityIndicator IsRunning and IsVisible, then you can solve your issue.
Related use ActivityIndicator step, you can take a look:
ActivityIndicator

Get the api controllers constructor value within an AuthorizeFilter

When the user is authenticated I want to prevent that he updates/deletes/reads data created from other accounts... by telling him you do not have the permission 403!
What is the best way to get an instance of the ISchoolyearService to invoke its HasUserPermission() method?
I know I could new up the SchoolyearService here but that would defeat the reason using an IoContainer at all in my app.
public class UserActionsSchoolyearAuthorizationFilter : AuthorizationFilterAttribute
{
public override void OnAuthorization(HttpActionContext actionContext)
{
if (actionContext != null)
{
bool canUserExecuteAction = false;
if (actionContext.Request.Method == HttpMethod.Put)
{
int schoolyearId = Convert.ToInt32(actionContext.Request.GetRouteData().Values["Id"]);
int userId = actionContext.Request.Content.ReadAsAsync<SchoolyearEditRequest>().Result.Schoolyear.UserId;
//var schoolyearService = actionContext.ControllerContext.Controller.GetContstructorParameterServiceInstance();
//canUserExecuteAction = schoolyearService.HasUserPermission(userId, schoolyearId);
if (canUserExecuteAction)
{
base.OnAuthorization(actionContext);
}
else
{
actionContext.Response = new HttpResponseMessage(HttpStatusCode.Forbidden);
}
}
// Removed for brevity
private readonly ISchoolyearService _service;
public SchoolyearController(ISchoolyearService service)
{
_service = service;
}
If you made the _service parameter public on your SchoolyearController you could try something like this in the OnAuthorization method:
var schoolyearController = actionContext.ControllerContext.Controller as SchoolyearController;
canUserExecuteAction = schoolyearController._service.HasUserPermission(userId, schoolyearId);
Ok finally I found it out how to get the ISchoolyearService from the current request:
Grab the registered service from the DependencyScope!
Now this Attribute should be put on the controller directly. Its not needed to put it on the action due to the if/else on the http verbs which I do.
bool canUserExecuteAction = false;
if (actionContext.Request.Method == HttpMethod.Put)
{
int targetId = Convert.ToInt32(actionContext.Request.GetRouteData().Values["Id"]);
int userId = actionContext.Request.Content.ReadAsAsync<SchoolyearEditRequest>().Result.Schoolyear.UserId;
var requstScope = actionContext.ControllerContext.Request.GetDependencyScope();
var service = requstScope.GetService(typeof(ISchoolyearService)) as ISchoolyearService;
canUserExecuteAction = service.HasUserPermission(userId, targetId);
if (canUserExecuteAction)
{
base.OnAuthorization(actionContext);
}
else
{
actionContext.Response = new HttpResponseMessage(HttpStatusCode.Forbidden);
}
}

Dart JavaScript output fails with: method not found: 'new ToDos:1:0' Receiver: Instance of 'JsClassMirror'

I've ported a handy JS library to Dart: dartscale. The crucial part of it's functionality can be broken down to:
final Map<Symbol, ClassMirror> _registeredModules = new Map<Symbol, ClassMirror>();
register(module, [String moduleName]) {
final uniqueModuleName = moduleName != null ? moduleName : module.runtimeType.toString();
final Symbol uniqueModuleIdentifier = new Symbol(uniqueModuleName);
if (_registeredModules.containsKey(uniqueModuleName)) {
throw new StateError("Module ${moduleName} already registered!");
}
final ClassMirror mirror = reflect(module).type;
_registeredModules[uniqueModuleIdentifier] = mirror;
}
start(Symbol moduleName, String id, options) {
if (!_registeredModules.containsKey(moduleName)) {
throw new StateError("Module ${moduleName} not registered!");
}
final ClassMirror mirror = _registeredModules[moduleName];
final Symbol moduleId = id != null ? new Symbol(id) : moduleName;
final Sandbox sandbox = new Sandbox(this.mediator);
if (_runningModules.containsKey(moduleId)) {
throw new StateError("Module with id #${moduleId} already running!");
}
final InstanceMirror moduleInstance = mirror.newInstance(new Symbol(''), [sandbox], null);
moduleInstance.invoke(new Symbol("start"), [options]);
_runningModules[moduleId] = moduleInstance;
}
i also provide an example
part of example;
class ToDos {
Sandbox _sandbox;
DivElement _contentEl;
int _nextToDoId = 0;
UListElement _todoList;
ToDos ([Sandbox this._sandbox]);
start([Map options]) {
this._initLocalStorage();
var html = ['<div id="module-todos">',
'<form>',
'<input type="text" class="input-medium">',
'<button type="submit" class="btn">Add</button>',
'</form>',
'<ul>',
'</ul>',
'</div>'].join('');
this._contentEl = new Element.html(html);
this._todoList = this._contentEl.query('ul');
options['containerEl'].append(this._contentEl);
window.localStorage.keys.forEach((key) => this._renderToDo(key));
this._setupEvents();
this._sandbox.channel('navigationbar').topic('filter').listen((filterContent) {
this._filter(filterContent);
});
this._sandbox.channel('navigationbar').topic('clearfilter').listen((filterContent) {
this._todoList.queryAll('li span').forEach((element) => element.parent.classes.remove('hide'));
});
}
stop() {
this._contentEl.remove();
}
_initLocalStorage() {
if (window.localStorage.keys.length == 0) {
var map = {
"1": {
"subject": "Groceries: Banas and Apples",
"isDone": false
},
"2": {
"subject": "Taxes: take care of them",
"isDone": false
},
"3": {
"subject": "Bring out trash",
"isDone": false
}
};
for (var key in map.keys) {
window.localStorage[key] = stringify(map[key]);
this._nextToDoId++;
}
}
else {
for (var key in window.localStorage.keys) {
var intKey = int.parse(key);
if (intKey > this._nextToDoId) {
this._nextToDoId = intKey;
}
this._nextToDoId++;
}
}
}
_setupEvents() {
var input = this._contentEl.query('input');
input.onKeyDown.listen((event) {
if (event.keyCode == KeyCode.ENTER) {
event.preventDefault();
this._addToDo(input.value);
input.value = '';
}
});
this._contentEl.query('button[type="Submit"]').onClick.listen((event) {
event.preventDefault();
if (input.value.length > 0) {
this._addToDo(input.value);
input.value = '';
}
});
this._todoList.onClick.listen((MouseEvent event) {
var el = event.target;
if (el.classes.contains('icon-remove')) {
this._deleteToDo(el.parent);
}
else if (el.classes.contains('icon-ok')) {
this._toggleToDoDone(el.parent);
}
});
}
_renderToDo(id) {
var todoObject = parse(window.localStorage[id.toString()]);
var html = ['<li class="record-todo ', todoObject["isDone"]?"done":"",'" data-id="', id,'">',
'<span>', todoObject["subject"], '</span>',
'<i class="icon icon-ok"></i>',
'<i class="icon icon-remove"></i>',
'</li>'].join('');
this._todoList.append(new Element.html(html));
}
_addToDo(text) {
var todoJson = stringify({
"subject": text,
"isDone": false
});
window.localStorage[this._nextToDoId.toString()] = todoJson;
this._renderToDo(this._nextToDoId);
this._nextToDoId++;
}
_deleteToDo(todoLIElement) {
window.localStorage.remove(todoLIElement.dataset["id"]);
todoLIElement.remove();
}
_toggleToDoDone(todoLIElement) {
var done = !todoLIElement.classes.contains('done');
var id = todoLIElement.dataset["id"];
var todoObject = parse(window.localStorage[id]);
todoObject["isDone"] = done;
window.localStorage[id] = stringify(todoObject);
if (done) {
todoLIElement.classes.add('done');
}
else {
todoLIElement.classes.remove('done');
}
}
_filter(content) {
this._todoList.queryAll('li span').forEach((element) {
if (element.innerHtml.contains(content)) {
element.parent.classes.remove('hide');
}
else {
element.parent.classes.add('hide');
}
});
}
}
in my App.dart
library example;
import 'dart:html';
import 'dart:json';
import '../lib/dartscale.dart';
part 'dart/ToDos.dart';
main () {
var core = new Core();
core.register(new ToDos());
core.start("ToDos", "ToDos", {
"containerEl": query('body > .container')
});
}
bug in dart2js ?
Solution
Turns out that dart2js has problems with mirrored calls on Methods/Constructors which have optional positional Arguments.
So changing
class ToDos {
Sandbox _sandbox;
ToDos([Sandbox this._sandbox]);
}
to
class ToDos {
Sandbox _sandbox;
ToDos(Sandbox this._sandbox); //make the argument non-optional
}
solved my Problem
This isn't really an answer, since you don't state what's going wrong, but some general advice. Mostly, I'd avoid new Symbol() and mirrors if you can easily avoid them, and in this case you can.
First, you should figure out if you want to register module instances or produce instances on demand, you probably don't want both like you are here. If you register an instance, then can't you just reuse that instance? Does start() need to produce new instances as part of its spec? You turn around and try to make sure that an instance isn't already running anyway.
If you really do need to produce instances, a simple factory function will eliminate the need for mirrors. So instead of:
core.register(new ToDos());
You write:
core.register('ToDos', () => new ToDos());
If you still want to use mirrors, you can clean up the use of new Symbol(). Here's some recommendations:
Don't use Symbols as keys unless you're really getting them from reflective APIs like mirrors and noSuchMethod in the first place. Just use the String name or maybe the runtimeType. In your case you're mixing Symbols and Strings as keys in your _registeredModules map, which is probably causing some bugs, like modules will never appear to be registered. (are you testing in checked mode?)
Don't use new Symbol('name'), use const Symbol('name')
Don't use InstanceMirror.invoke, getField, or setField when you can just call the method directly. In your code you can replace
moduleInstance.invoke(new Symbol("start"), [options]);
with
moduleInstance.reflectee.start(options);
Factories aren't evil. It'd be nice to invoke a constructor from a type instance, but until then registering a factory is pretty lightweight in Dart.
Here's your code with those suggestions:
typedef Object Factory(Sandbox sandbox);
final Map<Symbol, Factory> _registeredModules = new Map<Type, Factory>();
register(Type type, Factory factory) {
if (_registeredModules.containsKey(type)) {
throw new StateError("Module $type already registered!");
}
_registeredModules[type] = factory;
}
start(Type type, options) {
if (!_registeredModules.containsKey(type)) {
throw new StateError("Module $type not registered!");
}
if (_runningModules.containsKey(type)) {
throw new StateError("Module $type already running!");
}
Sandbox sandbox = new Sandbox(this.mediator);
var module = _runningModules[type](sandbox)..start(options);
_runningModules[type] = module;
}

Resources