In MEF how is the dependency chain of exports-imports evaluated? - mef

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.

Related

Error: #inject called with undefined (...)

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)?

Autofac Interface Ambiguity

"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.)

Problems compiling routes after migrating to Play 2.1

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

Play Framework Scala: routes with optional parameters not working in controller subpackages?

I'm trying to set up a route in the Playframework 2.0 (Scala) that includes optional parameters in the query string, following the examples in the documentation:
GET /my/path controllers.foo.Bar.list(offset: Int ?= 0, limit: Int ?= 20)
However when compiling, I get the following error message:
object controllers.foo.Bar does not take parameters
I made sure that the controllers.foo.Bar.list method does in fact take two Ints as parameters. One key observation (I hope) may be that this used to work previously, when I had the Controller class directly in the controllers package, i.e.
controllers.Bar.list
But it ceased working as soon as I introduced a "foo" subpackage in Controllers.
Any input on what I'm doing wrong highly appreciated!
UPDATE: Sorry - I did some more experimenting and it seems the reason is something entirely different (d'oh). In my concrete case, my controller class was
controllers.foo.List.list
and that seemed to cause a name clash. Renaming to something else ("FooList") solved the issue.
For anyone discovering this question, it seems very likely that this was due to a bug in the Play Framework.
You can follow its progress on the issue tracker ticket.

Obscure NSZombie console log

I tried searching on google, and got literally no results when trying to figure out what this means. My console is logging:
objc[17048]: Class _NSZombie_GEOLatLng is implemented in both ?? and ??. One of the two will be used. Which one is undefined.
objc[17048]: Class _NSZombie_GEOLatLng is implemented in both ?? and ??. One of the two will be used. Which one is undefined.
objc[17048]: Class _NSZombie_GEOLocation is implemented in both ?? and ??. One of the two will be used. Which one is undefined.
objc[17048]: Class _NSZombie_GEOLocation is implemented in both ?? and ??. One of the two will be used. Which one is undefined.
Anyone seen this before, or have any idea what it means, what's causing it, and if it's a problem?
I've seen it. Specifically, on OS X - but the cause should be the same. GEOLocation (and others) is defined in two images which are loaded into the process.
If that were a class you wrote, the class' symbols are defined in multiple object files (would likely be a linker error though…), in the linked libraries, loaded bundles, or some combination of - when code may be loaded dynamically.
If it's not a class you wrote (or synthesized), file a bug with the creator of the class.
It's also possible that the class is defined in your app, and also defined in a linked library. In that event, you would need to change the name of your class.
It is definitely a problem. The class (with that name) is being loaded into the objc runtime twice, and there are no guarantees as to which implementation will be returned when an instance is created since objc uses a flat namespace.
In this case, the class exists in the system frameworks so... send it to the bug reporter - it deserves be fixed quickly.
This is a harmless warning that occurs when you have enabled zombie warnings in the build scheme. You can ignore it.
I had this obscure message and noticed that a NIB had been removed from the project, but code was still using it. You may want to check if any resources have been removed from the bundle that are still in use.