"The ambiguity, is in the box" - Monty Python.
Autofac is having a problem resolving an interface. See attached solution.
The Interface, IAmbiguous, is defined in project ACommon. It is implemented in project AInjectable. The AInjectable project does not / cannot reference ACommon. The AInjectable project defines IAmbiguous as an existing item brought in with a file link.
The UI project calls ACommon Inject and attempts to register the AInjectable assembly. IAmbiguous is not ambiguous initially but after a builder.RegisterAssemblyTypes command it becomes "ambiguous in the namespace." There is no error thrown when the container is built but the registration is not there.
Registration can be done "AsImplementedInterfaces" if Named and Keyed is not used. But then there is no way to Resolve the registration because the service IAmbiguous is "ambiguous in the namespace."
This question was double-posted as an issue on Autofac. It is not an Autofac problem. I will copy/paste the answer from the issue in here; for future readers, if you want to see the repro solution, go check out the full issue
What you're doing by including the same interface in two different assemblies isn't something you should be doing. Note that by doing that, your AInjectable class is not implementing the interface from the ACommon project. It's implementing a different but identically named interface.
This sort of thing is a problem - having the same type (interface, class, whatever) name in two different assemblies. We even had a problem (#782) where we had a System.SerializableAttribute in Autofac as a shim for .NET Core. You really just can't do that.
You'll also see the same thing if you try to make a static extension method class that has the same namespace and name as some other static extension method class. Ambiguous references.
Without doing Reflection.Emit style code generation, you won't be able to declare an interface in one assembly ("Assembly A") and implement that interface in a different assembly ("Assembly B") without having Assembly B reference Assembly A. That's just how .NET works. What you're seeing is a manifestation of that when you use Autofac, but it's not caused by Autofac. It's caused by you doing something you shouldn't be doing in .NET.
The fix is to define your interfaces in a separate assembly that everyone implementing the interfaces can reference. (Or you can try to dynamically generate code using Reflection.Emit or Roslyn or something, but that's waaaay harder.)
Related
This is not the first time I work with Inversify, but never had a problem like such. Currently what I have in my project is just a bunch of decorated (properly, constructor injections) services, therefore I assume it's failing on building the metadata.
I'm getting Error: #inject called with undefined this could mean that the class X has a circular dependency problem. You can use a LazyServiceIdentifer to overcome this limitation. whenever I start the application (bear in mind - I don't have a container yet).
Following the "circular dependency problem" part I built a dependency graph using dependency-graph package and it shows no circular dependencies in my project, it also managed to properly generate registration order.
I'm wondering if there's any way to avoid using LazyServiceIdentifier everywhere in the project?
Additionaly I'm trying to understand how is it even possible for this error to occur when using constructor injection (and having no circular dependencies of course)?
I am having trouble finding faked Thread.Sleep in mscorlib.fakes library.
I am following direction at http://www.codewrecks.com/blog/index.php/2012/04/27/using-shims-in-visual-studio-11-to-test-untestable-code/
http://msdn.microsoft.com/en-us/library/d00bd51t(v=vs.100).aspx shows Thread.Sleep is in mscorlib so I added its fake but System.Threading.Fakes namespace doesn't contain ShimThread nor StubThread.
Thread is a sealed class but VS fake framework should be able to fake static method in sealed class.
This is very much possible. By default Fakes framework doesn't generate shims for most types (including types in System.Threading namespace) of mscorlib because Fakes framework itself makes use of mscorlib. So only a few of the types are shimmed,
However, you can configure this behavior by changing the mscorlib.fakes file added in your project.
<Fakes xmlns="http://schemas.microsoft.com/fakes/2011/">
<Assembly Name="mscorlib" Version="4.0.0.0"/>
<ShimGeneration>
<Add Namespace="System.Threading!"/>
</ShimGeneration>
</Fakes>
Now build the test project and you can see shims for types in the System.Threading namespace, including ShimThread.SleepInt32.
Read more about the .fakes xml file on this page
This is because the Shim framework cannot fake all .Net BCL classes in mscrolib and System, see: MSDN.
Unfortunately I couldn't find a list of types that aren't supported. But it seems, primarily types that are not pure CLR classes or need OS functionality (Thread, FileSystemWatcher, ...) are not supported at this time.
I'm a relative newbie to SystemVerilog.
I have a package with class A defined in it. This class uses a virtual interface, since
it's a driver (BFM) in a testbench. I'm using a package so I can use the same BFM in
other designs.
In my testbench, I import the A class and pass to it an instance of the virtual interface.
However, when a task in the class tries to assign a value to a signal in the interface, I'm getting a compilation error.
What am I doing wrong?
How can one package a BFM with a virtual interface?
Thanks,
Ran
SystemVerilog packages cannot include interfaces within the actual package. So your interface needs to be compiled along with you package source. The classes you define will reside in the package while the interface definition resides in the global scope where modules live.
Classes within packages can make references to virtual interfaces, but you need to make sure the interface is compiled and visible, apart from the package source.
Strictly according to the spec, I don't think this is possible since it adds an implicit external dependency:
Items within packages are generally type definitions, tasks, and
functions. Items within packages shall not have hierarchical
references to identifiers except those created within the package or
made visible by import of another package. A package shall not refer
to items defined in the compilation unit scope.
It doesn't say anything about the design element namespace, which is where interface declarations live, but accessing any member of an interface requires a hierarchical reference.
You should consider packages to be completely self-contained, other than pre-processor directives and import.
Generally the class declaration not present before its usage is resolved with the help of systemverilog typedef definition. For example "Class A uses Class B" and "Class B uses class A" then typedef is used to resolve the stalemate.
Now when you bring in the package with the above scenario then one needs to ensure both Class A and Class B have to be in same package. If they are not then the compile wont go through.
The reason being the SystemVerilog parser will need the definition of the classes indicated with the typedef at the end of the package parsing. This fails.
This issue needs to watched out that "typedef does not apply across package".
After migrating to Play-2.1 I stuck into problem that routes compiler stopped working for my routes file. It's been completely fine with Play-2.0.4, but now I'm getting the build error and can't find any workaround for it.
In my project I'm using cake pattern, so controller actions are visible not through <package>.<controller class>.<action>, but through <package>.<component registry>.<controller instance>.<action>. New Play routes compiler is using all action path components except for the last two to form package name that will be used in managed sources (as far as I can get code in https://github.com/playframework/Play20/blob/2.1.0/framework/src/routes-compiler/src/main/scala/play/router/RoutesCompiler.scala). In my case it leads to situation when <package>.<component registry> is chosen as package name, which results in error during build:
[error] server/target/scala-2.10/src_managed/main/com/grumpycats/mmmtg/componentsRegistry/routes.java:5: componentsRegistry is already defined as object componentsRegistry
[error] package com.grumpycats.mmmtg.componentsRegistry;
I made the sample project to demonstrate this problem: https://github.com/rmihael/play-2.1-routes-problem
Is it possible to workaround this problem somehow without dropping cake pattern for controllers? It's the pity that I can't proceed with Play 2.1 due to this problem.
Because of reputation I can not create a comment.
The convention is that classes and objects start with upper case. This convention is applied to pattern matching as well. Looking at a string there seems to be no difference between a package object and normal object (appart from the case). I am not sure how Play 2.1 handles things, that's why this is not an answer but a comment.
You could try the new # syntax in the router. That allows you to create an instance from the Global class. You would still specify <package>.<controller class>.<action>, but in the Global you get it from somewhere else (for example a component registry).
You can find a bit of extra information here under the 'Managed Controller classes instantiation': http://www.playframework.com/documentation/2.1.0/Highlights
This demo project shows it's usage: https://github.com/guillaumebort/play20-spring-demo
I'm facing an issue where I have App1.ClassA Importing App2.ClassB which itself needs to import App2.ClassC in a property. App1 and App2 are 2 different xaps
App1.ClassA invokes ComponentInitializer.SatisfyImports(this) in its initializing code. However this chain of satisfying imports does not seem to cascade down across assemblies.
I cannot specify ComponentInitializer on ClassB, since it is exporting itself (and MEF throws an error).However, ClassC is not being imported into the property of ClassB without this invocation.
Is this the expected behaviour or am i seeing some other bug due to which ClassC is not getting loaded ?
I went through this post -http://forums.silverlight.net/forums/t/202811.aspx, but the difference may be that i am crossing over Xaps in my scenario
Thanks in advance
i am crossing over Xaps in my scenario
By default, ComponentInitializer will find only parts in the current XAP. You can override this default host configuration by calling CompositionHost.Initialize.
The chain of resolving imports was being respected even when crossing over xap boundries. I'm guessing that xap boundries are not even an issue for xap, as it works at assembly level and as long as the assembly is available, it will resolve all the imports in the dependency chain.
The mistake i made was not realizing that the imports are not resolved during class instantiation( so the resolved elements are not available in the constructor). I had to hook up for the IPartInitialized Notification, and take action when this event is raised.
I'm marking this as the correct answer not to boost standings but to guide anyone facing the same issue.