bchavez / Bogus

:card_index: A simple fake data generator for C#, F#, and VB.NET. Based on and ported from the famed faker.js.
Other
8.82k stars 501 forks source link

Error in designer when used in constructor #89

Closed JerryNixon closed 7 years ago

JerryNixon commented 7 years ago

This works at runtime, this is an issue of during design time in the UWP-XAML designer. This occurs when the constructor of the view-model has the Generate() code. Listen, I really can't figure out the cause at this point; but, am very interested to integrate this library in the Template10.SampleData library and start teaching on Microsoft Virtual Academy using it. Thanks for looking.

Could not load file or assembly 'Bogus, Version=15.0.6.0, Culture=neutral, PublicKeyToken=fa1bb3f3f218129a' or one of its dependencies. The system cannot find the file specified.

image

bchavez commented 7 years ago

Hey @JerryNixon ,

Could you try installing System.Runtime? I'm not totally sure what's going on but this is the second time this has happened. Previously, another user vbehara encountered the same issue and posted in the gitter channel.

We definitely need to figure out what's going on here.

:boom: :fire: "Set it ablaze like a candle wick... Light it up, light it up..."

bchavez commented 7 years ago

Also, if you could send me a zip sample of your project I'll be happy to kill this bug with fire :beetle: :fire:.

JerryNixon commented 7 years ago

Well, with the Universal Windows Platform, there really isn't a system.runtime. Is there?

bchavez commented 7 years ago

I found the siutation odd too but vbehara mentioned it as his solution. Might try:

Install-Package System.Runtime -Version 4.3.0

IIRC, it's a type-forwarder assembly. I know this isn't really practical atm and Bogus should work out of the box with UWP.

I suspect there is some edge case I'm hitting (or I'm doing something really dumb) with NuGet tooling that pops up under UWP projects. I'm guessing NuGet and UWP are loading up the .NET Standard version of the Bogus DLL and it's got something to do with .NET Standard.

I don't have any UWP stuff installed on my local dev box; so this might take me a little longer to debug.

JerryNixon commented 7 years ago

It installed, yeah. But it didn't correct the err. The proj I am working on can be zipped here, I'll do it to help you resolve this. I am sure it's simple. I will be presenting this at VSLive tomorrow and will skip the design-time data part for now. It's fine.

JerryNixon commented 7 years ago

Bogus_Sample.zip

Here's a working demo. Just load it up and look at MainPage.xaml and ref the pic above.

image

bchavez commented 7 years ago

Ah, thanks very much. I was just about to ask about the VS version. I'll try to get this working but can't promise. My eyes are getting sleepy and VS is still installing UWP. Should be finishing up soon tho. Hopefully. "Finishing up: 100%"

:fallen_leaf: :leaves: "I get a sense of weightlessness…"

bchavez commented 7 years ago

Hi @JerryNixon ,

I spent some time investigating your issue. I am able to reproduce the issue in VS 2017 (15.3). However, I'm at an impasse on how to resolve the issue permanently. It's starting to look like more of a bug inside Visual Studio itself rather than a problem with Bogus.

I've narrowed down the problem and it seems the XAML designer XDesProc.exe that comes with Visual Studio 2017 (15.3) is at the core of this issue :imp:. First, I'll explain the workarounds, then later go into detail about what I think is causing the problem.

Workaround 1 - Disable project code

The easiest workaround is to Disable project code in the XAML designer to get rid of the error, but this doesn't solve the problem.

psp_516

The disadvantage of this workaround is you'll lose some design-time fidelity w.r.t some of your code running in the ViewModel constructor.

Workaround 2 - Install Bogus.dll in IDE\PrivateAssemblies

Using Bogus v11.04, manually download the NuGet package and extract it. Take bogus.11.0.4\lib\netstandard1.3\Bogus.dll DLL and copy it to the private assemblies folder of the Common7\IDE

C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\PrivateAssemblies 

Next,

With this crude workaround, you won't lose design-time fidelity like the previous workaround. But copying Bogus.dll to PrivateAssemblies is intrusive. Also, note: It's important to use v11.04 since this is the last Bogus version that was compiled against Newtonsoft.Json v9.0.1.

The Problem

I think the core problem is a combination of the CLR Loader (Fusion) running XDesProc.exe and flaky assembly Shadow Copying by Visual Studio/MSBuild.

From my limited understanding of Visual Studio's internal infrastructure, something (not sure who yet) Shadow Copies your program DLLs to a special folder:

C:\User\AppData\Local\\Microsoft\VisualStudio\15.0_xxx\Designer\ShadowCache\random.blah\...

Here's some output from procmon monitoring the paths Fusion is probing:

vmware_5092

Notice, how Fusion tries to find Bogus.dll in all the wrong places. Even c:\user\.nuget\packages\bogus\... is missing from the probe search.

To make matters worse, I get the feeling UWP is using some custom environment (WinRT?) because the fuslogvw.exe output was no help in determining the binding failure. The fuslogvw.exe output looks totally different from a normal .NET/CLR application binding failure:

*** Assembly Binder Log Entry  (8/18/2017 @ 5:14:10 PM) ***

The operation failed.
Bind result: hr = 0x80070002. The system cannot find the file specified.

Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll
Running under executable  C:\Users\___\AppData\Local\Microsoft\VisualStudio\15.0_d91727fb\Designer\ShadowCache\jf0gvpp0.b3m\qrmmgdc1.k3k\XDesProc.exe
--- A detailed error log follows. 

BEGIN : Framework bind.
END   : The provided identity format is not recognized. (Exception from HRESULT: 0x80132003)
BEGIN : Windows Runtime Type bind.
END   : The provided identity format is not recognized. (Exception from HRESULT: 0x80132003)
BEGIN : Immersive bind.
END   : The system cannot find the file specified. (Exception from HRESULT: 0x80070002)
BEGIN : Framework bind.
END   : The provided identity format is not recognized. (Exception from HRESULT: 0x80132003)
BEGIN : Windows Runtime Type bind.
END   : The provided identity format is not recognized. (Exception from HRESULT: 0x80132003)
BEGIN : Immersive bind.
END   : The system cannot find the file specified. (Exception from HRESULT: 0x80070002)
BEGIN : Framework bind.
END   : The provided identity format is not recognized. (Exception from HRESULT: 0x80132003)
BEGIN : Windows Runtime Type bind.
END   : The provided identity format is not recognized. (Exception from HRESULT: 0x80132003)
BEGIN : Immersive bind.
END   : The system cannot find the file specified. (Exception from HRESULT: 0x80070002)

Breakpointing on the type load exception by CLR with WinDbg wasn't much help either. The !CLRStack just shows a normal call to Activator.CreateInstance of some type.


More problematic for XDesProc.exe is, even if we take Bogus totally out of the picture and reference the latest version (v10.0.3) of Newtonsoft.Json (via NuGet package) and use it in our ViewModel:

public class ViewModel
{
   public ViewModel()
   {
       this.Message = JsonConvert.SerializeObject(new { foo = "bar" });
   }
   public string Message { get; set; }
}

We encounter, in the XAML designer:

psp_517

Could not load file or assembly 'Newtonsoft.Json, Version=10.0.0.0, Culture=neutral,
PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies.
The bound assembly has a version that is lower than that of the request.
(Exception from HRESULT: 0x80132000)

So, we can't even use the latest version of Newtonsoft in the XAML designer because XDesProc.exe already forcefully bound a lower version (ver 9) to the app domain. Bummer.


Additionally, these XAML designer issues only happen with the x86 configuration. ARM and x64 seem to Disable project code in the XAML designer automatically (see workaround 1 above).


Overall, I think a combination of all these: XDesProc.exe, flaky shadow copying, & incomplete runtime CLR probing are all contributing factors to your issue. If we can't use the latest version of Newtonsoft in our ViewModel alone, we sure as heck can't use the latest version of Bogus because we're currently compiled against v10.

Without looking at the source code of Visual Studio itself and understanding more about the infrastructure in place for the XAML designer; this is about as far as I can go to help you. I think you'll have to contact the team owner(s) of XDesProc.exe to get to the bottom of this. Feel free to /cc them here if they are on GitHub.

Wish I could help more. :+1:

Sorry I failed you, :cry: Brian

:watch: :city_sunset: "I just can't wait... I just can't wait... for saturday night..."

bchavez commented 7 years ago

Hi @JerryNixon ,

I have really good news to share. Your UWP project sample with Bogus works in the XAML designer now. I recently dropped the Newtonsoft dependency (see #98) which was at the core of your issue. Bogus now uses a BSON format for locale data a homegrown BSON deserializer as a replacement.

Below is a screenshot of your UWP sample working:

vmware_742

Some things you'll need to get Bogus to working as shown above:

I did have to hit "reload designer" a few times after making changes, but I think that's probably a VS thing rather than something we're doing inside Bogus. If it turns out we can improve the experience, let me know. Also, I only tested x86 and x64 architectures.

Lastly, for completeness, here are the updated sources of your sample project files with Bogus working: Bogus_Sample_WORKING.zip

Please feel free to re-open the issue if you continue to have trouble.

Many thanks, Brian

:dizzy: :boom: Chaos Chaos - Do You Feel It?