StructureMap : EqualToAppSetting with non string constructor argument - inversion-of-control

Given
public class Blah : IBlah
{
public Blah(decimal argument)
{
}
}
When
ForRequestedType<IBlah>()
.TheDefault.Is.OfConcreteType<Blah>()
.WithCtorArg("argument")
.EqualToAppSetting("argument_app_setting_key")
Then StructureMap throws the following exception
No Default Instance defined for PluginFamily System.Decimal
Is there any way to use the EqualToAppSetting with non-string arguments ?

I don't think you can do this with the EqualToAppSetting method. Could you not just reference System.Configuration and cast the app setting yourself? Like this...
ForRequestedType<IBlah>()
.TheDefault.Is.OfConcreteType<Blah>()
.WithCtorArg("blah")
.EqualTo(Convert.ToDecimal(ConfigurationManager.AppSettings["argument_app_setting_key"]));

Related

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?

Entity Framework execute stored procedure with params

Ok, hope to not get too many flags, but it's to annoying.
I have a method in my controller which calls a method from another class:
offerForCreate.Rating = CalculateRating.CreateRating(addOffer);
and entire called class :
public class CalculateRating
{
private readonly DataContext mainContext;
public CalculateRating(DataContext mainContext)
{
this.mainContext = mainContext;
}
// calcul rating oferte noi
public decimal CreateRating(OfferForCreate offer)
{
decimal rating = mainContext.Database.FromSql<decimal>("RatingCalculator", offer.locationId, offer.typeId);
return rating;
}
}
I get an error when try to execute this procedure:
Error CS1061: 'DatabaseFacade' does not contain a definition for 'FromSql' and no extension method 'FromSql' accepting a first argument of type 'DatabaseFacade' could be found
and another if I don't create an instance of CalculateRating class in my controller :
Controllers\AnnouncesController.cs(127,37): error CS0120: An object reference is required for the non-static field, method, or property 'CalculateRating.CreateRating(OfferForCreate)
Everywhere I see must specify the entity, but what entity I can specify if my stored procedure use multiple tables?
Asp.Net Core Web API
You can execute stored proc like this:
using (var command = mainContext.Database.GetDbConnection().CreateCommand())
{
command.CommandType = System.Data.CommandType.StoredProcedure;
command.CommandText = "dbo.RatingCalculator";
var locationIdParam = new System.Data.SqlClient.SqlParameter("#locationId", System.Data.SqlDbType.Int);
locationIdParam .Value = offer.locationId;
//DO same for typeId parameter
//Params to Parameters collection
command.Parameters.Add(locationIdParam);
command.Connection.Open();
return (double)command.ExecuteScalar();
}
Controllers\AnnouncesController.cs(127,37): error CS0120: An object reference is required for the non-static field, method, or property 'CalculateRating.CreateRating(OfferForCreate)
This error is occuring because if you declare CalculateRating as static you can not reference in non-static field mainContext.
You should create an instance of your CalculateRating class using Dependency Injection. Here are steps:
Create an interface ICalculateRating
public interface ICalculateRating {
decimal CreateRating(OfferForCreate offer);
}
Update CalculateRating class to implement ICalculateRating
Register the DBContext and ICalculateRating mappings in ConfigureServices method of Startup.cs file like this:
services.AddDbContext<DbContext>(opts=> { opts.UseSqlServer("sqlserver conntection string") }, ServiceLifetime.Scoped);
services.AddTransient<ICalculateRating, CalculateRating>();
In your controller constructor, input an argument of type ICalculateRating which will be injected by Microsoft Dependency Injection framework at runtime:
private readonly ICalculateRating _calculateRating;
public MyController(ICalculateRating calculateRating) {
_calculateRating = calculateRating;
}
You can then call the method like this:
offerForCreate.Rating = _calculateRating.CreateRating(addOffer);

Is there a way to have a get only (no set) in a typescript interface?

I have a case where I want to have just a get in the interface, no set. Is there a way to do that?
If not, we can implement a set and throw an exception if it is called. But it's cleaner if we can have just a get.
At present I have:
export interface IElement {
type : TYPE;
}
export class Element implements IElement {
public get type () : TYPE {
return TYPE.UNDEFINED;
}
public set type (type : TYPE) {
this.type = type;
}
}
I would like to have my interface & class be:
export class Element implements IElement {
public get type () : TYPE {
return TYPE.UNDEFINED;
}
}
TypeScript interfaces cannot currently define a property as read-only. If it's important to prevent, you'll need to throw an exception/error at runtime to prevent sets within the setter for the property.
The compiler doesn't require that you implement the get and a set though. You can just implement the get for example. However, at runtime, it won't be caught.

Interface query parameter parsing?

I believe this is not possible, but I just wanted to verify.
I would like to do something like...
#Path("/awesome")
public class MyRestResource {
#GET
public void coolQuery(#QueryParam("user") User) {
// ...
}
}
public interface User {
String name();
Address address();
}
(Please don't comment on the example... it's completely made-up and not my use case.)
I imagine this is not possible because Jersey/JAX-RS generally requires a static method public static T valueOf(String input) which obviously is not possible with interfaces.
That said, is there any work-around for this to have a query parameter be an interface? And if so, how do you specify the parser / parsing logic?
Thanks
According to the documentation there are more ways than just the static valueOf method:
Be a primitive type;
Have a constructor that accepts a single String argument;
Have a static method named valueOf or fromString that accepts a single String argument (see, for example, Integer.valueOf(String) and java.util.UUID.fromString(String));
Have a registered implementation of javax.ws.rs.ext.ParamConverterProvider JAX-RS extension SPI that returns a javax.ws.rs.ext.ParamConverter instance capable of a "from string" conversion for the type. or
Be List<T>, Set<T> or SortedSet<T>, where T satisfies 2 or 3 above. The resulting collection is read-only.
The solution using a ParamConverterProvider should work in this case.

Cast class to base interface via reflection cause exception

I'm loading a .NET assembly dinamically via reflection and I'm getting all the classes that it contains (at the moment one). After this, I'm trying to cast the class to an interface that I'm 100% sure the class implements but I receive this exception: Unable to cast object of type System.RuntimeType to the type MyInterface
MyDLL.dll
public interface MyInterface
{
void MyMethod();
}
MyOtherDLL.dll
public class MyClass : MyInterface
{
public void MyMethod()
{
...
}
}
public class MyLoader
{
Assembly myAssembly = Assembly.LoadFile("MyDLL.dll");
IEnumerable<Type> types = extension.GetTypes().Where(x => x.IsClass);
foreach (Type type in types)
{
((MyInterface)type).MyMethod();
}
}
I have stripped out all the code that is not necessary. This is basically what I do. I saw in this question that Andi answered with a problem that seems the same mine but I cannot anyway fix it.
You are trying to cast a .NET framework object of type Type to an interface that you created. The Type object does not implement your interface, so it can't be cast. You should first create a specific instance of your object, such as through using an Activator like this:
// this goes inside your for loop
MyInterface myInterface = (MyInterface)Activator.CreateInstance(type, false);
myInterface.MyMethod();
The CreateInstance method has other overloades that may fit your needs.