In which package, can I find "AlsoNotifyChangeFor" in .Net MAUI? - maui

I'm using the package CommunityToolkit.Mvvm 8.0.0 in .Net MAUI.
I have a simple class as follows :
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Collections;
using CommunityToolkit.Mvvm.DependencyInjection;
using CommunityToolkit.Mvvm.Messaging;
namespace My.ViewModels
{
public partial class BaseViewModel:ObservableObject
{
public BaseViewModel()
{
}
[ObservableProperty]
[AlsoNotifyChangeFor(nameof(IsNotBusy))] <<<< Compilation error here
bool isBusy;
[ObservableProperty]
string title;
public bool IsNotBusy => !isBusy;
}
}
This class raises a compilation error on the attribute AlsoNotifyChangeFor.
It says The type or namespace name could not be found for this attribute to be used.
Does anyone know please where can I find the right package to use this attribute ?
Thanks.

in the release notes, under breaking changes
[AlsoNotifyChangeFor] ---> [NotifyPropertyChangedFor]

Related

C# 9 default implementations causing errors [duplicate]

Here is a my code inside a c# project that targets .NET Core 3.0 (so I should be in C# 8.0) with Visual Studio 2019 (16.3.9)
public interface IJsonAble
{
public string ToJson() => System.Text.Json.JsonSerializer.Serialize(this);
}
public class SumRequest : IJsonAble
{
public int X { get; set; }
public int Y { get; set; }
public void Tmp()
{
new SumRequest().ToJson(); //compile error
}
}
The compile error is:
CS1061 'SumRequest' does not contain a definition for 'ToJson' and no accessible extension method 'ToJson' accepting a first argument of type 'SumRequest' could be found (are you missing a using directive or an assembly reference?)
Can someone shed some light on this behavior ?
Methods are only available on the interface, not the class. So you can do this instead:
IJsonAble request = new SumRequest()
var result = request.ToJson();
Or:
((IJsonAble)new SumRequest()).ToJson();
The reason for this is it allows you to add to the interface without worrying about the downstream consequences. For example, the ToJson method may already exist in the SumRequest class, which would you expect to be called?
Try using (new SumRequest() as IJsonAble).ToJson(); to help the compiler a bit.
Anyway, I'm sure what you're after is (this as IJsonAble).ToJson(), assuming you want to apply ToJson on current SumRequest instance.

Can not access interface default implementation method from within derived class [duplicate]

Here is a my code inside a c# project that targets .NET Core 3.0 (so I should be in C# 8.0) with Visual Studio 2019 (16.3.9)
public interface IJsonAble
{
public string ToJson() => System.Text.Json.JsonSerializer.Serialize(this);
}
public class SumRequest : IJsonAble
{
public int X { get; set; }
public int Y { get; set; }
public void Tmp()
{
new SumRequest().ToJson(); //compile error
}
}
The compile error is:
CS1061 'SumRequest' does not contain a definition for 'ToJson' and no accessible extension method 'ToJson' accepting a first argument of type 'SumRequest' could be found (are you missing a using directive or an assembly reference?)
Can someone shed some light on this behavior ?
Methods are only available on the interface, not the class. So you can do this instead:
IJsonAble request = new SumRequest()
var result = request.ToJson();
Or:
((IJsonAble)new SumRequest()).ToJson();
The reason for this is it allows you to add to the interface without worrying about the downstream consequences. For example, the ToJson method may already exist in the SumRequest class, which would you expect to be called?
Try using (new SumRequest() as IJsonAble).ToJson(); to help the compiler a bit.
Anyway, I'm sure what you're after is (this as IJsonAble).ToJson(), assuming you want to apply ToJson on current SumRequest instance.

How to write C# implementation for a Q# operation with intrinsic body?

I have created a library in C# to be used in Q# programs. The library has two scripts, a C# class library called "Class1.cs" and a matching Q# script called "Util.qs", I share the code snippet of each here:
Class1.cs:
using System;
using Microsoft.Quantum.Simulation.Common;
using Microsoft.Quantum.Simulation.Core;
using Microsoft.Quantum.Simulation.Simulators;
namespace MyLibrary {
class Class1 : QuantumSimulator {
static void Method_1 (string str) { ... }
.
.
.
}
}
Util.qs:
namespace MyLibrary {
operation Op_1 (str : String) : Unit { body intrinsic; }
}
There is another Q# program in a different namespace that uses the namespace "MyLibrary" so after adding reference, in this Q# program I have:
namespace QSharp
{
open Microsoft.Quantum.Canon;
open Microsoft.Quantum.Intrinsic;
open MyLibrary;
operation TestMyLibrary() : Unit {
Op_1("some string");
}
}
When I execute "dotnet run" in the terminal I receive this message:
Unhandled Exception: System.AggregateException: One or more errors
occurred. (Cannot create an instance of MyLibrary.Op_1 because it is
an abstract class.) ---> System.MemberAccessException: Cannot create
an instance of MyLibrary.Op_1 because it is an abstract class.
How can I fix it?
Thanks.
UPDATE:
Following Mariia' answer and also checking Quantum.Kata.Utils, I changed my code as following:
So, I changed Class1 script to:
using System;
using Microsoft.Quantum.Simulation.Common;
using Microsoft.Quantum.Simulation.Core;
using Microsoft.Quantum.Simulation.Simulators;
namespace MyLibrary {
class Class1 : QuantumSimulator {
private string classString = "";
public Class1() { }
public class Op_1_Impl : Op_1{
string cl_1;
public Op_1_Impl (Class1 c) : base (c) {
cl_1 = c.classString;
}
public override Func<string, QVoid> Body => (__in) => {
return cl1;
};
}
}
Now the error messages are:
error CS0029: Cannot implicitly convert type 'string' to 'Microsoft.Quantum.Simulation.Core.QVoid'
error CS1662: Cannot convert lambda expression to intended delegate type because some of the return types
in the block are not implicitly convertible to the delegate return type
Having checked Quantum.Kata.Utils, I realised I need to create a field and a constructor for Class1 which is a base class and also I should override Func<string, QVoid> as the Op_1 parameter is string type. But I am not sure if each of these steps individually is done properly?
Second Update:
I have changed the previous c# code in first update to the following one:
using System;
using Microsoft.Quantum.Simulation.Common;
using Microsoft.Quantum.Simulation.Core;
using Microsoft.Quantum.Simulation.Simulators;
namespace MyLibrary {
class Class1 : QuantumSimulator {
public Class1() { }
public class Op_1_Impl : Op_1{
Class1 cl_1;
public Op_1_Impl (Class1 c) : base (c) {
cl_1 = c;
}
public override Func<string, QVoid> Body => (__in) => {
return QVoid.Instance;
};
}
}
Now the error message is the same as the very first one:
Unhandled Exception: System.AggregateException: One or more errors
occurred. (Cannot create an instance of MyLibrary.Op_1 because it is
an abstract class.) ---> System.MemberAccessException: Cannot create
an instance of MyLibrary.Op_1 because it is an abstract class.
And also in this new code shouldn't the constructor public Class1() { } have a parameter? if so what datatype?
In your code, there is nothing connecting the Q# operation Op_1 and the C# code that you intend to implement it in Method_1.
Q# operations are compiled into classes. To define a C# implementation for a Q# operation with the intrinsic body, you have to define a class that implements the abstract class into which your Q# operation gets compiled; so you would have something like public class Op_1_Impl : Op_1.
Getting all the piping right can be a bit tricky (it's a hack, after all!) I would recommend looking at the operation GetOracleCallsCount and its C# implementation to see the exact pieces that have to be in place for it to work.
For the updated question, the signature of your method says that it takes string as an input and returns nothing (QVoid), but the implementation tries to return a string cl_1, so you get a Cannot implicitly convert type 'string' to 'Microsoft.Quantum.Simulation.Core.QVoid'.
To provide a custom C# emulation for your Op_1 Q# operation, you'll need to replace your Class1.cs with something like this:
using System;
using Microsoft.Quantum.Simulation.Core;
namespace MyLibrary
{
public partial class Op_1
{
public class Native : Op_1
{
public Native(IOperationFactory m) : base(m) { }
public override Func<String, QVoid> Body => (str) =>
{
// put your implementation here.
Console.WriteLine(str);
return QVoid.Instance;
};
}
}
}
You can then run the Test1Library using the QuantumSimulator.
That being said, as Mariia said, this is kind of hacky, undocumented functionality that might change in the future, may I ask why you need this?

Scaffold EF Core entities with interface

I am using Entity Framework Core tools to create Entities and DBContext from the existing database.
Scaffold-DbContext "Server=XXXXXX;Database=MyDB;User ID=xxxx;Password=xxxxxxx" Microsoft.EntityFrameworkCore.SqlServer -ContextDir .-OutputDir Entities -Force
This working. But is there any way to scaffold all the entities with known interface? So i have interface IEntityBase and i want all the entities to have this interface
Note
This question is specific to EF Core 2+ and scaffolding
Update 1
So as per the SO Suggesion i have created CSharpEntityTypeGenerator and IDesignTimeServices The accepted answer is not valid for EF Core > 2.* so i am using the suggession from #Chris Peacock
public class MyEntityTypeGenerator: CSharpEntityTypeGenerator
{
public MyEntityTypeGenerator(ICSharpHelper cSharpHelper)
: base(cSharpHelper)
{
}
public override string WriteCode(IEntityType entityType, string #namespace, bool useDataAnnotations)
{
string code = base.WriteCode(entityType, #namespace, useDataAnnotations);
var oldString = "public partial class " + entityType.Name;
var newString = "public partial class " + entityType.Name + " : EntityBase";
return code.Replace(oldString, newString);
}
}
public class MyDesignTimeServices: IDesignTimeServices
{
public void ConfigureDesignTimeServices(IServiceCollection serviceCollection)
{
serviceCollection.AddSingleton<ICSharpEntityTypeGenerator, MyEntityTypeGenerator>();
}
}
There is one change i had to make. CSharpEntityTypeGenerator constructor takes ICSharpHelper as parameter instead of ICSharpUtilities
These two classes are in Data assembly which is not a startup project.
At package manager console i executed the scaffolding command again. However i do not see generated entities have base class.
How scaffolding framework would know to use my custom generator? I am adding generator in serviceCollection but looks like the code never get executed
Am i missing something?
You can use EF Core Power Tools with Handlebars templates to achieve this.
https://github.com/ErikEJ/EFCorePowerTools/wiki/Reverse-Engineering#customize-code-using-handlebars
I think these options should have been provided as as a part of EF Scaffolding tool by default.
But here is my code. I am using Microsoft.EntityFrameworkCore.Design 2.2.4 and Microsoft.EntityFrameworkCore.SqlServer 2.2.4 and based on my experience with .NET Core this may change in future version
CSharpEntityTypeGenerator
public class MyEntityTypeGenerator: CSharpEntityTypeGenerator
{
public MyEntityTypeGenerator(ICSharpHelper cSharpUtilities)
: base(cSharpUtilities)
{
}
public override string WriteCode(IEntityType entityType, string #namespace, bool useDataAnnotations)
{
Console.WriteLine(entityType.Name);
string code = base.WriteCode(entityType, #namespace, useDataAnnotations);
var oldString = "public partial class " + entityType.Name;
var newString = "public partial class " + entityType.Name + " : EntityBase";
return code.Replace(oldString, newString);
}
}
By default scaffolding generates classes with the same name as Table name. In our case the table names are Pluralize, but we want class name Singularize. So you have to implement Microsoft.EntityFrameworkCore.Design.IPluralizer. I used Inflator utility. However, note that i could not add Inflector using Nuget in .Net Core project. Looks like it does not support .NET Core yet. So i have added the single code file instead in my project.
IPluralizer
public class MyPluralizer : IPluralizer
{
public string Pluralize(string identifier)
{
return Inflector.Pluralize(identifier) ?? identifier;
}
public string Singularize(string identifier)
{
return Inflector.Singularize(identifier) ?? identifier;
}
}
IDesignTimeServices
You need to add this class in startup project. Initially, i had this class in the same project as other classes but that did not work. I moved this class in startup project, (In my case that is ASP.NET Core project) and it worked
public class MyDesignTimeServices : IDesignTimeServices
{
public void ConfigureDesignTimeServices(IServiceCollection serviceCollection)
{
// Start debugger
System.Diagnostics.Debugger.Launch();
serviceCollection.AddSingleton<ICSharpEntityTypeGenerator, MyEntityTypeGenerator>();
serviceCollection.AddSingleton<IPluralizer, MyPluralizer>();
}
}

How do I implement an InfoWindowAdapter interface in Xamarin?

I am using Xamarin and I am wanting to create a CustomWindowAdapter that implements a GoogleMap.InfoWindowAdapter interface.
I have tried this so far:
public class CustomWindowAdapter : InfoWindowAdapter
{
}
I am getting this error:
Error CS0246: The type or namespace name 'InfoWindowAdapter' could not be found (are you missing a using directive or an assembly reference?)
Here is the documentation for the interface: https://developers.google.com/maps/documentation/android/reference/com/google/android/gms/maps/GoogleMap.InfoWindowAdapter
Can I please have some help?
What using statement do I need to use?
Thanks in advance
Step 1: Get Google Play Services component from Component Store
Step 2: Implement GoogleMap.IInfoWindowAdapter
using Android.Gms.Maps;
using Android.Gms.Maps.Model;
using Android.Views;
public class InfoWindow : Java.Lang.Object, GoogleMap.IInfoWindowAdapter
{
#region IInfoWindowAdapter implementation
public View GetInfoContents(Marker p0)
{
throw new NotImplementedException ();
}
public View GetInfoWindow(Marker p0)
{
throw new NotImplementedException ();
}
#endregion
}