At my level of experience with Unity it might be faster to ask whether the "generics handling" bug acknowledged by ctavares back in 2008 was fixed in a public release.
Here was the problem (which might be my problem today):
Hi,
I get an exception when using ....
container.RegisterType(typeof(IDictionary<,>),
typeof(Dictionary<,>));
The exception is...
"Resolution of the dependency failed,
type = \"IDictionary2\", name = \"\".
Exception message is: The current
build operation (build key Build
Key[System.Collections.Generic.Dictionary2[System.String,System.String],
null]) failed: The current build
operation (build key Build
Key[System.Collections.Generic.Dictionary2[System.String,System.String],
null]) failed: The type Dictionary2
has multiple constructors of length
2. Unable to disambiguate.
When I attempt...
IDictionary
myExampleDictionary =
container.Resolve>();
Here was the moderated response:
There are no books that'll help, Unity is a little too new for publishers to have caught up yet.
Unfortunately, you've run into a bug in our generics handling. This is currently fixed in our internal version, but it'll be a little while before we can get the bits out. In the meantime, as a workaround you could do something like this instead:
public class WorkaroundDictionary : Dictionary
{
public WorkaroundDictionary() { }
}
container.RegisterType(typeof(IDictionary<,>),typeof(WorkaroundDictionary<,>));
The WorkaroundDictionary only has the default constructor so it'll inject no problem. Since the rest of your app is written in terms of IDictionary, when we get the fixed version done you can just replace the registration with the real Dictionary class, throw out the workaround, and everything will still just work.
Sorry about the bug, it'll be fixed soon!
According to the Unity Team:
Just wanted to let folks know we've
released the bits that have the
generics fixes in them. Take a look
and let us know what you think. It's
checked into codeplex source control.
You may need to get the latest source and build yourself (2.x) as the bug fix may not have been packaged yet.
Related
When I try to build my Xamarin.Droid project I get following Build error:
2>R8 : warning : Missing class: java.lang.ClassValue
2>R8 : error : Compilation can't be completed because some library classes are missing.
I got this error from one day to another... Is there a way to find out where java.lang.ClassValue is needed, or add it manual?
Edit:
I did some research and got new informations: When I build the solution on another maschine (I this case Microsofts AppCenter) it builds without any problems. So I thought that my solution is fine, maybe there are problems with the android sdk or the jdk.
So I created a new Xamarin.Forms project and build the android part, that worked without any problems. So the android sdk or jdk seems to be fine.
Not that this is a solution exactly, but it may point you in the right direction. I'm currently getting this message as a result of a bound Android-library under our own maintenance. When I remove the NuGet from our project, the message disappears and the code compiles. Obviously I can't make use of the program features using this library then either, but at least it looks like the library is causing the issue... May be it could be the same in your case?
What fixed the issue for me
After I knew which library was causing issues, I decided to dive it a bit more with a demo-app I had written specifically to test that library. From here I found out that enabling d8-dexing or r8-code-shrinking together with multi-dexing is what caused the issue. You can use either or, so:
Turn of code-shrinker options such as ProGuard or r8, and use d8-dexing.
Turn of multi-dexing, use d8-dexing and optionally a code-shrinker.
My suggestion is to use the latter, as with d8-dexing, your dexed reference-table should be much more efficient and smaller anyway, meaning you might not even need multi-dexing any more.
In addition, it seems the above resolution doesn't play to nicely with linking, so set linking options to "None".
Problems on a Mac CI
After I fixed all of the above I ran into a further issue when trying to compile our app on a Mac CI, which told me Mono.Android.dll could not be AOT-compiled. This, apparently, is an issue with the file being too big for LLVM on a Mac, though, as described here, for which the solution is to simply turn off LLVM.
A better way of fixing it
Today I was pointed to another set of potential fixes highlighted here. This page actually mentions three fixes, of which option B is the preferred one as this is in-line with "the upstream recommendation from the Google Guava library" (cited from this thread).
For me option A - reverting to dx-dexing - didn't quite work, as, though I was able to remove the warning pertaining to java.lang.ClassValue, I got a whole bunch of other warnings back. Option B, using ProGuard-rules used in combination with R8, was a better choice in that respect, since this allowed me to get rid of all the other warnings as well. In fact, though, this removed the difference between options B & C, as their outcome thereby became the same. Yet, just following the suggestions in this document, my app started crashing on launch. To resolve this, I had to check for errors in Logcat, which showed me a class that was needed was being linked away. Adding another rule to explicitly keep that class then finally resolved the remainder of the problem, giving me the below ProGuard-configuration:
-dontwarn java.lang.ClassValue
-dontwarn kotlin.jvm.internal.Lambda
-dontwarn kotlin.jvm.functions.Function1
-dontwarn kotlin.jvm.internal.markers.KMappedMarker
-dontwarn kotlin.jvm.functions.Function0
-dontwarn kotlin.coroutines.jvm.internal.SuspendLambda
-dontwarn kotlin.jvm.functions.Function2
-keep class com.google.android.material.internal.BaselineLayout
With this configuration, I'm now once again able to use both AOT and LLVM.
I am adding some modifications to an existing .Net-Core & Entity Framework-using webapp.
There is dependency injections used, and by now we have 22 lines of calling the AddTransient()-Method. Sadly I am the "chosen one", who is adding the 23rd call, and the webapp shows some strange behaviour. I debugged as deep as possible, and get stuck when I see a message: Ein Ausnahmefehler des Typs "System.StackOverflowException" ist in Microsoft.Extensions.DependencyInjection.dll aufgetreten.
Translated to english something like: An Exception of type "System.StackoverflowException" was raised in Microsoft.Extensions.DependencyInjection.dll
I am pretty sure the constructor of the 23rd class is built the same way as those 22 before. And if I disable another addTransient-Call, so there are 22 addTransient-calls again, the webapp works as is should. That's why I am assuming some limitation.
Did you encounter the same behaviour? Or are there some resources to read about limitations regarding Microsoft.Net Dependency Injection and what can be done in that case?
You very likely have a circular dependency. Examine the new class you are trying to register and review its dependencies. Better yet, remove all its dependencies temporarily and try again to register.
Due to some legal restrictions we cannot post the vital part of the source, and we neither do not have the time to rewrite it, to make it public available.
But we tried different things, and found out, changing the IoC-Container from Microsoft .net DI to Autofac had a positive impact, and the error went away.
I know, this will be no satisfying answer for all of you, but feel free to ask, if you want to know some specific details. But maybe it confirms your thoughts about giving Autofac (or any other IoC-Container) a chance.
I'll just cut to the chase and give you some background information: Our application has quite massive startup issues, taking up to 20(!!) seconds for our webservice to respond to the first request. Everything runs quite fast after this initial lag, but the initial lag itself is quite a big problem.
At any rate, I've been doing research on the issue for the past two days or so, I have managed to get a proper log of requests sent back and forth and it turned out that the issue lies in creating XMLSerializer, which quite simply takes ages.
Now after even more googling, I have discovered the 'Generate serialization assembly' property and that it doesn't quite work properly. To force the serialization, I have followed this solution over here:
https://stackoverflow.com/a/8798289/2401855
Now that has actually worked, except... Well, it didn't. When I try to compile the webservice, Sgen throws the 'There was an error reflecting type' error and I can't quite proceed. And finally, here come my questions:
How do I get the actual error Sgen.exe has thrown? It might just help me understand what's going on better, but I was trying to look into system log files that codeproject was referring to and didn't quite find anything.
Why does the error get thrown in the first place? It gets thrown for this particular bit of code:
public class Enums
{
public enum TypNakladu
{
Prijmy = 1,
Vydaje = 2
}
public static string GetEnumDescription(Enum value)
{
FieldInfo fi = value.GetType().GetField(value.ToString());
DescriptionAttribute[] attributes =
(DescriptionAttribute[])fi.GetCustomAttributes(
typeof(DescriptionAttribute),
false);
if (attributes != null &&
attributes.Length > 0)
return attributes[0].Description;
else
return value.ToString();
}
}
'TypNakladu' is the enum that sgen doesn't seem to like. Is there any way to make sgen to just ignore this particular class, or enums contained within? (there are more, but when I comment one out, sgen just complains about the next one)
And that's just about it I suppose. I'm sorry if I'm making some incredibly dumb mistake here, I'm not very experienced when it comes to ASP.NET webservices.
Very well, now I actually have some answers, so here we go:
As for error thrown by Sgen.exe, the best way to get was to quite simply not run it via Visual Studio IDE and just navigate to the folder with my server. I didn't do it in the first place because running Sgen.exe directly gave me even more errors - turns out I've had two versions of Sgen installed on my harddrive. They came natively with two installations of Visual Studio.
Now for the error itself, problem was that there were two instances of the same enum name, as simple as that.
I've added the necessary using statement. using System.Collections.Generic to the top of my class and the compiler happily accepts my use of Lists, but when I'm debugging I'm getting a very weird debugging problem in that when I expand my lists instead I get:
unknown type 'System.Collections.Generic.CollectionDebuggerView'1 mscorlib.
What possible reasons could there be? Google didn't seem to help me...
The lists do seem to declare their information when declared and empty and they are defined with a class I've created, but I've never seen this issue in any other toolkit such as XNA etc.
I shoudl also mention that this is through MonoDevelop I see this error.
Thanks.
It was a bug in Mono according to these release notes. It's patched in 2.10.2, but Unity isn't using the patched Mono build.
679586: Unknown type System.Collections.Generic.CollectionDebuggerView
error when viewing Parametrized collection in debugger
Unity uses Mono 2.6. Without access to the source for Unity, I'm not sure how you can implement that patch. Even with the source, 2.6 is still the stable build so 2.10.2 so it may cause issues elsewhere.
Used .ToArray() method to convert my List<T> to T[] array. Just don't forget to sweep this code in release!
Quick and dirty workaround which works for me:
private class CellList : List<Cell> {}
Somehow it displays correctly in debugger.
I've just downloaded the dynamic object framework Clay and am running into issues regarding castle project versions. Clay uses functionality from v2.0 of "castle" whilst I have a project which has been started referencing v2.5. Needless to say just to make matters more interesting I'm a complete beginner in all things "Castle" and IoC.
The real problem is that upgrading the references within clay solution results in a depreciated method warning. Regardless of whether you supress the method or not, the provided unit tests fail with a "Cannot perform runtime binding on a null reference" exception in the following code in "Intercept" of "InterfaceProxyBehavior":
var invoker = BindInvoker(invocation);
invoker(invocation);
The code that produces the run-time warning is in "CreateInstance" of "DefaultClayActivator":
//var proxyType = _builder.CreateClassProxy(baseType, options);
var proxyType = _builder.CreateClassProxyType(baseType, null, options);
As previously stated I'm still a complete beginner with Castle Windsor and just starting out with IoC so haven't even come across the Proxy stuff yet. Frustratingly I have no idea what the error message is even telling me, or asking for.
Have anyone already ported Clay across to version 2.5 of the castle project, so know the steps needed. Or can any one with experience of this part of castle throw anymore light on the error and what I may need to do to resolve it.
Updated
I'm still not really any the wiser as to the functionality that is failing, but have had chance to revisit the code running it both with v2.0 (works) and v2.5 (breaks) in castle.core. Attached are two images of the debug information when it works and then when it breaks. The test that it fails on is below, I've indicated the call with a comment.
namespace ClaySharp.Tests {
[TestFixture]
public class BinderFallbackTests {
...
[Test]
public void TestInvokePaths() {
var dynamically = ClayActivator.CreateInstance<Alpha>(new IClayBehavior[] {
new InterfaceProxyBehavior(),
new AlphaBehavior()
});
Alpha statically = dynamically;
IAlpha interfacially = dynamically;
Assert.That(dynamically.Hello(), Is.EqualTo("World-"));
Assert.That(statically.Hello(), Is.EqualTo("World-"));
Assert.That(interfacially.Hello(), Is.EqualTo("World-")); // <- Fails on this call
Assert.That(dynamically.Foo(), Is.EqualTo("Bar-"));
Assert.That(interfacially.Foo(), Is.EqualTo("Bar-"));
Assert.Throws<RuntimeBinderException>(() => dynamically.MissingNotHandled());
}
...
}
}
This is the debug information when using v2.5 of castle.core and the exception is thrown:
This is the debug information using v2.0 of castle.core (which works) for the same call / line that causes the problem with v2.5
It seems I fixed this. (all tests passing)
See the workitem on codeplex I created and the changes I pushed to my fork:
http://clay.codeplex.com/SourceControl/network/Forks/remcoros/Clay
I have never used this Clay thing, so all stuff below is based on assumptions.
The error message from BindInvoker is not a Castle error, but I'm guessing it's happening because the invoker is trying to bind to invocation target of the proxy which in DynamicProxy 2.1 used to have a value in some cases, which was wrong, and later versions 2.2 and 2.5 fixed that but it was a breaking change that you're now experiencing.
The other error message is telling you
Use CreateClassProxyType method
instead.
Which is the other method you commented out. What's not obvious here?
Some nice tutorials on Clay dynamic objects:
Malleable C# dynamic objects Part 1 Link
Malleable C# dynamic objects Part 2 Link.