How to dependency-inject an interface with multiple generic types in asp.net core [duplicate] - asp.net-core

I am using WebAPI in ASP.NET Core.
This works:
services.AddScoped<IApiKeysService, APIKeysService>();
Now that the interface is returning a generic type T This does not
services.AddScoped<IApiKeysService>();
Error Using the generic type blah requires 1 type Arguments
Or this
services.AddScoped<IApiKeysService<T>>();
I get the following compile error
type or namespace T cannot be found
How do I register it in Startup.cs?
NOTE: I cannot use a concrete type because the interface member is a base class with generic method.

Interfaces
You cannot instantiate an interface, so it is not possible to register an interface without an implementation type (whether generic or not).
However, it is possible to register types as the concrete type instead of an interface.
services.AddScoped(typeof(Foo<>));
Which is specified in the constructor as:
public MyService(Foo<ClosingType> foo)
{
// implementation
}
Open Generics
Open generics are always specified the same way in .NET: typeof(SomeGenericType<>).
services.AddScoped(typeof(IFoo<>), typeof(Foo<>));
If there are multiple open generic parameters, you would specify how many using commas. For example, with 2 open generic parameters:
services.AddScoped(typeof(IFoo<,>), typeof(Foo<,>));

Related

How to get only declared members (not inherited) with Kotlin Reflection?

Is there any way to get only the declared members of a class (not inherited) with Kotlin Reflection?
Something equivalent to getDeclaredMethods(), or ...Fields(), in Java, but for members and JVM free, which:
Returns an array containing Method objects reflecting all the declared methods of the class ... but excluding inherited methods.
Or like a binding flag, such as BindingFlags.DeclaredOnly of dotnet.
Because the reflection is based on the class, So the following is only for the kotlin/JVM, not suitable for the Kotlin/JS or Kotlin/Native.
For the Kotlin/JS it supports limit, for detail, you can see this
document
The only supported parts of the API are: (::class),KType and typeOf
Firstly, you can use the SomeClass::class.java.declaredMethods to get the
getDeclaredMethods. That is the java method. Because the Kotlin file after compiled it is still a class. so you can directly use it.
You can also add the kotlin reflect to get the KClass, then use the declaredFunctions to get. Here is the Document
Returns all functions declared in this class. If this is a Java class, it includes all non-static methods (both extensions and non-extensions) declared in the class and the superclasses, as well as static methods declared in the class
For how to get the KClass, you can use the following code
Class.forName("mypackage.MyClass").kotlin.declaredFunctions
Besides the method, the other property you can also get. such as
declaredMembers
Returns all functions and properties declared in this class. Does
not include members declared in supertypes.
allSuperclasses
functions
Returns all functions declared in this class, including all non-static methods declared in the class and the superclasses, as well as static methods declared in the class.
you can read the document using it.

How can deserialization of polymorphic trait objects be added in Rust if at all?

I'm trying to solve the problem of serializing and deserializing Box<SomeTrait>. I know that in the case of a closed type hierarchy, the recommended way is to use an enum and there are no issues with their serialization, but in my case using enums is an inappropriate solution.
At first I tried to use Serde as it is the de-facto Rust serialization mechanism. Serde is capable of serializing Box<X> but not in the case when X is a trait. The Serialize trait can’t be implemented for trait objects because it has generic methods. This particular issue can be solved by using erased-serde so serialization of Box<SomeTrait> can work.
The main problem is deserialization. To deserialize polymorphic type you need to have some type marker in serialized data. This marker should be deserialized first and after that used to dynamically get the function that will return Box<SomeTrait>.
std::any::TypeId could be used as a marker type, but the main problem is how to dynamically get the deserialization function. I do not consider the option of registering a function for each polymorphic type that should be called manually during application initialization.
I know two possible ways to do it:
Languages that have runtime reflection like C# can use it to get
deserialization method.
In C++, the cereal library uses magic of static objects to register deserializer in a static map at the library initialization time.
But neither of these options is available in Rust. How can deserialization of polymorphic objects be added in Rust if at all?
This has been implemented by dtolnay.
The concept is quite clever ans is explained in the README:
How does it work?
We use the inventory crate to produce a registry of impls of your trait, which is built on the ctor crate to hook up initialization functions that insert into the registry. The first Box<dyn Trait> deserialization will perform the work of iterating the registry and building a map of tags to deserialization functions. Subsequent deserializations find the right deserialization function in that map. The erased-serde crate is also involved, to do this all in a way that does not break object safety.
To summarize, every implementation of the trait declared as [de]serializable is registered at compile-time, and this is resolved at runtime in case of [de]serialization of a trait object.
All your libraries could provide a registration routine, guarded by std::sync::Once, that register some identifier into a common static mut, but obviously your program must call them all.
I've no idea if TypeId yields consistent values across recompiles with different dependencies.
A library to do this should be possible. To create such a library, we would create a bidirectional mapping from TypeId to type name before using the library, and then use that for serialization/deserialization with a type marker. It would be possible to have a function for registering types that are not owned by your package, and to provide a macro annotation that automatically does this for types declared in your package.
If there's a way to access a type ID in a macro, that would be a good way to instrument the mapping between TypeId and type name at compile time rather than runtime.

Managed client implementing interfaces defined in managed COM object

I'd like to have a managed com object that exposes methods which accept as arguments objects implementing given interfaces. Something like this
[ComVisible(true)]
[Guid(".....")]
class SomeClass {
public void SomeMethod(ISomeInterface arg)
.....
Apparently ISomeInterface should also be declared ComVisible.
Now I want to consume that COM object in a managed client and call SomeMethod there. The problem is I need to instantiate an object that implements ISomeInterface. If that was a native COM object I'd get an interop assembly generated automatically and that won't be a problem. One cannot generate an interop assembly for managed COM object though.
I see that .NET 4.0 introduces the type equivalence concept. It looks like I could generate an interop manually using the ComImport attribute. But that looks like a pretty nasty job. I guess I could also use the TypeIdentifierAttribute but the documentation on that is vague and it says it's mostly intended for use by compilers.
So are there any other ways to do that?

Why can I not use the KnownType attribute in my WCF class?

I am using WCF to retrieve a collection of objects. The objects are all of type ProcedureText but may be of child classes SuspensionText or ResumptionText, both of which inherit from ProcedureText.
public class ProcedureText { }
public class SuspensionText : ProcedureText { }
public class ResumptionText : ProcedureText { }
My OperationContract specifies a method returning an array of ProcedureText objects:
[OperationContract]
[WebGet(UriTemplate = "procedureTexts")]
ProcedureText[] GetProcedureTexts();
This works if I cast all my objects to ProcedureText but I want to keep the distinction of using the sub-types. I had hoped to use the KnownType attribute to do this and had expected to be able to do it by adding it to my ProcedureText class:
[System.Runtime.Serialization.KnownType(typeof(SuspensionTextDto))]
[System.Runtime.Serialization.KnownType(typeof(ResumptionTextDto))]
public class ProcedureText { }
This doesn't work because the compiler cannot resolve System.Runtime.Serialization.KnownType. I know from the document that the attribute is part of .NET Framework 4, but I am using .NET Framework 4 and that is the Target Frameweork for my project.
Why do I need to set to be able to use the attribute?
The relevant DLL containing that type is not added by default. You need to add a reference to:
System.Runtime.Serialization
The usage is described in the documentation:
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.knowntypeattribute.aspx
Basically it is so that the serializer recognises the type. Your service contract returns an array of the base class, however the types in that array could be more derived. If the serializer is not told this, the serialization will fail I think.
Without explicitly adding the reference to the project, I was able to use " I was able to use "using System.Runtime.Serialization" in my code but when I used attributes like "KnownType" or "DataMember" the compiler gave an error.
I was able to overcome this issue by explicitly adding the reference. Go to "Add References" in your project and search for "System.Runtime.Serialization" under Assemblies and add the dll to the project.
Works in .net 4.5 and 4.5.1 so I assume this will work in 4.0 as well.

BlazeDS - Conversion from ArrayList <BaseClass> on java side to Actionscript

So we have a java class with two ArrayLists of generics. It looks like
public class Blah
{
public ArrayList<ConcreteClass> a;
public ArrayList<BaseClass> b;
}
by using [ArrayElementType('ConcreteClass')] in the actionscript class, we are able to get all the "a"s converted fine. However with "b", since the actual class coming across the line is a heterogeneous mix of classes like BaseClassImplementation1, BaseClassImplementation2 etc, it gets typed as an object. Is there a way to convert it to the specific concrete class assuming that a strongly typed AS version of the java class exists on the client side
thanks for your help!
Regis
To ensure that all of your DTO classes are marshalled across AS and Java, you need to define each remote class as a "remote class" in AS by using the "RemoteClass" attribute pointing to the java class definition like this [RemoteClass(alias="com.myco.class")].
BlazeDS will perform introspection on the class as it is being serialized/de-serialized and convert it appropriately (see doc below). It doesn't matter how the classes are packed or nested in an array, as long as it can be introspected it should work.
If you need special serialization for a class you can create your own serialization proxys (called beanproxy) by extending "AbastractProxy" and loading them into blazeds using the PropertyProxyRegistry register method on startup.
You will find most of this in the Blaze developers guide http://livedocs.adobe.com/blazeds/1/blazeds_devguide/.
Creating your own beanproxy class look here: //livedocs.adobe.com/blazeds/1/javadoc/flex/messaging/io/BeanProxy.html