Autofac fails to inject an object into the constructor, which it does resolve directly - autofac

I am experiencing a weird behavior with Autofac where I can use a container to resolve a type, say TypeA, but if I try resolve a type TypeB that needs TypeA object injected into the constructor, then container fails to resolve TypeA parameter!
Here is what my code looks like:
public class TypeA
{
}
public class TypeB
{
public TypeB(TypeA obj)
{
}
}
This works:
var obj = container.Resolve<TypeA>();
But this does not:
var obj = container.Resolve<TypeB>();
It throws the following exception:
DependencyResolutionException: None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'MyNamespace.TypeB' can be invoked with the available services and parameters:
Cannot resolve parameter 'MyNamespace.TypeA obj' of constructor 'Void .ctor(MyNamespace.TypeA)'.
Autofac.Core.Activators.Reflection.ReflectionActivator.UseSingleConstructorActivation.AnonymousMethod__0(Autofac.Core.Resolving.Pipeline.ResolveRequestContext, System.Action<Autofac.Core.Resolving.Pipeline.ResolveRequestContext>)
Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.BuildPipeline.AnonymousMethod__1(Autofac.Core.Resolving.Pipeline.ResolveRequestContext)
Autofac.Core.Resolving.Middleware.DisposalTrackingMiddleware.Execute(Autofac.Core.Resolving.Pipeline.ResolveRequestContext, System.Action<Autofac.Core.Resolving.Pipeline.ResolveRequestContext>)
Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.BuildPipeline.AnonymousMethod__1(Autofac.Core.Resolving.Pipeline.ResolveRequestContext)
Autofac.Core.Resolving.Middleware.ActivatorErrorHandlingMiddleware.Execute(Autofac.Core.Resolving.Pipeline.ResolveRequestContext, System.Action<Autofac.Core.Resolving.Pipeline.ResolveRequestContext>)
Strange thing is that I cannot reproduce this problem in a sample code that I can publish here. It works as expected in the sample project.
Does anyone have any idea what I could be doing that is causing my application code to behavior this way?
Thanks

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?

Class from Interface.cll

I'm trying to implement a class instance of an interface class. Exploring the interface (.NET DLL) with the project explorer, it says:
bool CreateInstance(SharedLibrary::MemoryArbiter^ pntMemory,
SharedLibrary::clsMessageQueue^ pntMessageQueue,
SharedLibrary::clsGPIO^ pntGPIO,
SharedLibrary::Types^ pntProgramSettings,
SharedLibrary::DisplayDriver^ pntDisplayDriver)
Member from Plugin_Interface::IPlugin
But if I write in my MyClass.h:
using namespace System;
using namespace System::ComponentModel;
using namespace SharedLibrary;
namespace MyCppPlugin {
[AttributeUsageAttribute(AttributeTargets::Class | AttributeTargets::Method |
AttributeTargets::Property | AttributeTargets::Field,
AllowMultiple = true, Inherited = false)]
ref class MyPlugin abstract : public Plugin_Interface::IPlugin
{
bool CreateInstance(SharedLibrary::MemoryArbiter^ pntMemory,
SharedLibrary::clsMessageQueue^ pntMessageQueue,
SharedLibrary::clsGPIO^ pntGPIO, SharedLibrary::Types^
pntProgramSettings, SharedLibrary::DisplayDriver^ pntDisplayDriver);
};
};
It says: "error C3766: Missing implementation of Plugin_Interface::IPlugin::CreateInstace(...)
What the heck do I do wrong?
EDIT:
Forgot the abstract statement.
And: Why is it saying "IntelliSense: Class can not implement interface member function "Plugin_Interface::IPlugin::CreateInstance" (declared in "Plugin_Interface.dll")"
???
You got a lot more diagnostic messages from this snippet, you are making several mistakes:
[AttributeUsage] is only valid on a class that derives from System::Attribute. You no doubt need to use some kind of attribute so that the plugin host can recognize your class as a valid plugin candidate, I can't guess what that attribute might be.
A method that implements an interface method should be public.
A method that implements an interface method must be virtual.
The method signature must be an exact match with the interface method declaration.
Just in case: you must actually implement the method, not just declare it.
The third and forth bullets are the chief reasons for the "must provide an implementation of the interface method" compile error. So proper code ought to resemble something like this:
[NoIdeaWhatAttribute]
public ref class MyPlugin : public Plugin_Interface::IPlugin {
public:
virtual bool CreateInstance(SharedLibrary::MemoryArbiter^% pntMemory,
SharedLibrary::clsMessageQueue^% pntMessageQueue,
SharedLibrary::clsGPIO^% pntGPIO,
SharedLibrary::Types^% pntProgramSettings,
SharedLibrary::DisplayDriver^% pntDisplayDriver)
{
// Todo...
return false;
}
};
I got it. Thanks to Hans Passant who gave me so many hints :)
To export the function it has to implement the Interface 1:1. The export statement has to be added over the class header:
[Export(IPlugin::typeid)]
public ref class MyPlugin : public Plugin_Interface::IPlugin
And: While VB.NET will compile to "Any CPU" and C++/CLI will compile to Win64/Win32 it will missfit. Both Projects have to have the same target - either 64bit OR 32bit.
Now it works.

gwt: How do I write a clone() method that doesn't result in "The method clone() is undefined for the type Object" error?

I'm using GWT 2.4. I have this class, which overrides the clone() method ...
public class Attribute implements Serializable, Cloneable {
...
public Object clone() {
Object ret = null;
try {
ret = super.clone();
} catch (CloneNotSupportedException e) {
} // try
return ret;
}
Sadly, when I try and run my GWT test class, I get the compilation error
[ERROR] Line 113: The method clone() is undefined for the type Object
Anyone know how I can rewrite the above to avoid the compile errors while preserving the functionality? Thanks, - Dave
Object.clone is not supported by the GWT compiler. If you really need support for it you can follow a work around suggested in this GWT issue: http://code.google.com/p/google-web-toolkit/issues/detail?id=5068

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.

Using Moq with Windsor -- Object of Type Moq.Mock[IFoo] cannot be converted to IFoo

I'm trying to set up some Moq repositories to test my service with Castle Windsor as my IOC. Mu service depends on IFoo, so I'm creating a moq instance that implements IFoo and injecting it into the container like so:
_container.AddComponent("AutoBill",
typeof (AutoBillService), typeof (AutoBillService));
var mockUserRepository = new Mock<IUserRepository>();
var testUser = new User()
{
FirstName = "TestFirst",
LastName = "TestLast",
UID=1
};
mockUserRepository.Setup(repo => repo.GetUser(testUser.UID))
.Returns(testUser);
_container.Kernel.AddComponentInstance("UserRepository",
typeof(IUserRepository), mockUserRepository);
var service = _container.Resolve<AutoBillService>(); //FAIL
Doing this gives me an exception:
System.ArgumentException: Object of type 'Moq.Mock`1[IUserRepository]' cannot be converted to type 'IUserRepository'
Can anyone see what I'm doing wrong?
You should pass mockUserRepository.Object instead of mockUserRepository.
This would be a lot more evident if you used the strongly typed API:
_container.Register(Component
.For<IUserRepository>()
.Instance(mockUserRepository.Object));
This compiles because the Object property implements IUserRepository.
I head the same problem with Castle Windsor.
A dinamyc initialization with method:
container.Register(Component.For<IUserRepository>()
.Instance(mockUserRepository.Object));
didn't work until I removed from my caslteRepository.config file pre-initialized repositories (like your IUserRepository) and left container "empty" from repositories.