Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot use CompositeDisposable library from nuget(System.Reactive) #342

Closed
WhitePhoera opened this issue Jan 23, 2019 · 9 comments
Closed

Cannot use CompositeDisposable library from nuget(System.Reactive) #342

WhitePhoera opened this issue Jan 23, 2019 · 9 comments
Assignees
Labels
bug

Comments

@WhitePhoera
Copy link

@WhitePhoera WhitePhoera commented Jan 23, 2019

Release Type: Official Release(from launcher)

Version: 3.1.0.1-beta01-0398

Platform(s): Windows and Android(probably will be all)

Describe the bug
I trued to add library from nuget, and after any use of it, i can't build project.
(tryed System.Reactive(CompositeDisposable) and Autofac)

To Reproduce
1)Start new project(i used Samples=>UI=>Game menu UI)
2)open VS
3)add nuget package with library ReactiveUI.(i used 4.2) into MainMenu.Game
4)Open MainScene.cs and add

        readonly System.Reactive.Disposables.CompositeDisposable disposables = new System.Reactive.Disposables.CompositeDisposable();

somewhere inside scene class
5)try to compile solution(not just game part) and got error

Expected behavior
Simply run project with Rx.

Log and callstacks
build.log
whole log, main issue is

System.IO.FileNotFoundException: Не удалось загрузить файл или сборку "System.Reactive, Version=4.2.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263" либо одну из их зависимостей. Не удается найти указанный файл.

it can't load assembly System.Reactive or one of it's dependancy.(cannot find file specified)

Additional context
tryed newtonsoft.json as well, looks like this happens with libraries which have additional libraryes as well.(but i am not sure)

@WhitePhoera WhitePhoera added the bug label Jan 23, 2019
@WhitePhoera

This comment has been minimized.

Copy link
Author

@WhitePhoera WhitePhoera commented Jan 23, 2019

current workaround i found is:

  1. do not use such classes directly inside scene class(and other classes which will be scanned by Xenko), so i use wrapper class(aka ViewModel for example)
  2. do not create object of wrapper/ViewModel in constructor(or initializer), create it at start.

not best, but at least i can use those.

----------added
well, still not best, since that wrapper cannot inherit from class from such 'bad' library.

@Kryptos-FR

This comment has been minimized.

Copy link
Collaborator

@Kryptos-FR Kryptos-FR commented Jan 23, 2019

That type is probably not serializable (see https://doc.xenko.com/latest/en/manual/scripts/public-properties-and-fields.html). Try adding it as a private field/property.

I have no issue building it from Visual Studio and running the game. But there seems to be an issue to open the solution in the GameStudio afterwards , f the field is public, because of serialization.

Alternatively, if you want to have that property/field public, you can "hide" it to the GameStudio (and serialization) by using the [DataMemberIgnore] attribute, such as:

using System.Reactive.Disposables;
using Xenko.Core;

public class MainScript : UISceneBase
{
    [DataMemberIgnore]
    public CompositeDisposable disposables = new CompositeDisposable();

    //...
}
@WhitePhoera

This comment has been minimized.

Copy link
Author

@WhitePhoera WhitePhoera commented Jan 23, 2019

it's already private.(no modifier at all)
from what i see, main issue that asset compiler can't resolve this type.(actually it can't resolve assembly from it)
i found two possible places to error

  1. in just that repro, asset compiler tryes to create object of scene, and due to initializer it will fail, with assembly not found reason.
  2. in method with side class(my connent with workaround), assembly compiler will fail even before that.
    here:
    foreach (var type in assembly.GetTypes())

    Cuz it will not be able to resolve base class of type it wanna touch.
    class MainScriptViewModel : ReactiveObject, IDisposable
    {
        readonly CompositeDisposable disposables = new CompositeDisposable();

        public void Dispose()
        {
            disposables.Dispose();
        }
    }

from what i see, asset compiler, does not tryes to resolve runtime dependancies.(also why ever it touches private types?)
with that we very limited to what code we can write, currently i can't derive any type from ReactiveObject(it's from main dependancy ReactiveUI).
this is very strange for me.

@WhitePhoera

This comment has been minimized.

Copy link
Author

@WhitePhoera WhitePhoera commented Jan 23, 2019

well, i was able to build crutch around that, by patching asset compiler.

		private static int Main(string[] args)
		{
			AppDomain.CurrentDomain.AssemblyResolve += Program.CurrentDomain_AssemblyResolve;
			int result;
			try
			{
				result = new PackageBuilderApp().Run(args);
			}
			catch (Exception ex)
			{
				Console.WriteLine("Unexpected exception in AssetCompiler: {0}", ex);
				result = 1;
			}
			return result;
		}

		private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
		{
			if (args.Name.StartsWith("Microsoft.Build"))//skip ms build assemblies, 
			{
				return null;
			}
			string path = Path.Combine(Directory.GetCurrentDirectory(), new AssemblyName(args.Name).Name + ".dll");//try to find requested dll in current directory.
			if (File.Exists(path))
			{
				return Assembly.LoadFrom(path);
			}
			path = Path.Combine(Directory.GetCurrentDirectory(), "../../Windows", Path.GetFileName(Directory.GetCurrentDirectory()), new AssemblyName(args.Name).Name + ".dll");
			if (File.Exists(path)) // else try to find that assembly exactly in windows build directory(was used for android build, but that probably wrong, cuz assemblies must be some where resolvable)
			{
				return Assembly.LoadFrom(path);
			}
			return null;
		}

with that patch it now can load not direct dependancies, but that very wrong.
asset compiler can at least do that itself, cuz it have better info.

@Kryptos-FR

This comment has been minimized.

Copy link
Collaborator

@Kryptos-FR Kryptos-FR commented Jan 23, 2019

There might be something else wrong in your setup or the way you have added that dependency. The code I have shown works perfectly, compiles and run.

@WhitePhoera

This comment has been minimized.

Copy link
Author

@WhitePhoera WhitePhoera commented Jan 23, 2019

i made one error in repro steps.
i added, not System.Reactive directly, but ReactiveUI, which depends from System.Reactive.

now i ended up with two projects, one compiling and second have that error, code is same inside ><.

setup was just fresh Xenko, as well as dep was added from VS and nuget.

@WhitePhoera

This comment has been minimized.

Copy link
Author

@WhitePhoera WhitePhoera commented Jan 25, 2019

still can't understand the reasons.
AssetCompiler just don't wanna load System.Reactive and all..
latest and fresh Xenko, latest VS2017 Community, latest Win10.

GameMenu4.zip
here is the project Xenko created(after repro step), may be something wrong with it?

@Kryptos-FR

This comment has been minimized.

Copy link
Collaborator

@Kryptos-FR Kryptos-FR commented Jan 25, 2019

@xen2 I could reproduce. It fails when the Game project is built with netstandard but is fine when the Game project is built with net461. I also tried to upgrade the Windows project to net472, but it doesn't make any difference.

What's puzzling is that it fails in some Yaml stack trace which I don't see how it could be relevant: Output-Build.txt.

@WhitePhoera in the meantime, change the Game project to target net461 instead of netstandard.

@WhitePhoera

This comment has been minimized.

Copy link
Author

@WhitePhoera WhitePhoera commented Jan 25, 2019

@Kryptos-FR ty, it worked.
i targeted net471 and monoandroid81 to touch android as well, and it worked.

so looks like issue exactly in netstandard, may be this is due to fact that netstandard libs don't copyes deps to them.
for example when i build those two targets, all Game deps near it.
image

but for netstandard in output dir we have only Game itself.
image

about YAML, i did not researched deep how it works, but looks like it build serializer and some basic yaml(or probably this is yaml from gamestudio, asset settings) and then tryes to deserialize it, so it creates object of our type, and here we have fail, since it can't create it.
still, looks like main issue is in loading deps for netstandard library.

@xen2 xen2 closed this in 0dcbaaf Feb 5, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.