| Author |
Share Topic Topic Search Topic Options
|
Wayne
Newbie
Joined: 14-Feb-2010
Location: Florida
Posts: 3
|
Post Options
Quote Reply
Topic: Attempting to mock data at *design* time Posted: 26-Dec-2011 at 11:38pm |
Interesting - I had installed Silverlight 5 but then uninstalled it and went back to Silverlight 4 on this development machine. Additional - while stepping though each line after asking Blend to open User Control for designing - IdeaBlade.Core.IdeaBladeConfig.Instance.ProbeAssemblyNames.Add(typeof(NorthwindIBEntities).Assembly.FullName);
is the first line of code that fails (subsequent deserialization also fails) - but executing the code to use the design data during a regular run and stepping though the code - that line resolves the conflict, succeeds and the cached data load properly. I will look into the possibility are some left overs of Silverlight 5 after reverting back to Silverlight 4. Is there an example of the "Data Mother" class available that you could share > Thank you for your help.
|
 |
WardBell
IdeaBlade
Joined: 31-Mar-2009
Location: Emeryville, CA,
Posts: 338
|
Post Options
Quote Reply
Posted: 26-Dec-2011 at 9:53pm |
Are you sure about the cause that you have identified? Could it be a null exception encountered during deserialization.Have you loaded Silverlight 5 by chance? I ask because there is a critical serialization bug in the Silverlight 5 release (RTW) acknowledged by Microsoft; apparently they took a dependence on a serialization method that does not exist in desktop .NET 4. "So what?" Well both Cider and Blend are actually running desktop .NET 4 when they display your Silverlight XAML. Too bad for all of us; serialization does not work. Microsoft has no intention of "fixing" SL 5 to address this. They have advised us that the developer should either revert to SL 4 (remove all SL 5 from the machine) or hang on for .NET 4.5; you can try a CTP of .NET 4.5. Frankly, we don't think any of these workarounds are appropriate. We are trying to find something else to recommend; no luck so far. It doesn't look good for designing with data that has been restored from an Entity Cache file ... or for any tactic that involves (de)serialization. For now we suggest that you create design data dynamicall with a "Data Mother" class: a class that instantiates design-time entities and populates an offline EntityManager; these become the data source for design time data binding. We regret the (temporary) loss of the entity cache file feature. I wish we knew a way around it. I'll certainly let you know if we come up with something. Root for .NET 4.5 I guess. If this is not the immediate cause of your problem and you are willing to live entirely in SL 4, please post again with more detail and we can get you going.
|
 |
Wayne
Newbie
Joined: 14-Feb-2010
Location: Florida
Posts: 3
|
Post Options
Quote Reply
Posted: 26-Dec-2011 at 2:23pm |
Following this thread with version 6.1.3 in a Silverlight app - loading from cache works fine at runtime but in Blend (design time) this line now seems to cause a failure: IdeaBlade.Core.IdeaBladeConfig.Instance.ProbeAssemblyNames.Add(typeof(NorthwindIBEntities).Assembly.FullName);
Debugging Blend design time with VS2010 - Blend cannot seem to figure out whether to add the assembly name to IdeaBlade.Core or IdeaBlade.Core.SL (common names inside) So the line fails and so then EntityCacheState.Restore(res.Stream)
fails too with null exceptions for each field and record during the load. Is there a work-around to add the assembly full names ? Thank you in advance.
|
 |
mikedfox
Newbie
Joined: 29-Apr-2010
Posts: 21
|
Post Options
Quote Reply
Posted: 06-Dec-2010 at 10:46am |
|
thanks Ward, that did the trick
|
 |
WardBell
IdeaBlade
Joined: 31-Mar-2009
Location: Emeryville, CA,
Posts: 338
|
Post Options
Quote Reply
Posted: 05-Dec-2010 at 10:15am |
@Mike - I posted an update to our BookShelf sample application so that it now uses an EntityCacheState for design time data. The zip includes a long document with a chapter on this subject. Find it at http://www.ideablade.com/BookShelfDF/BookShelfDF.zip. I just posted that chapter in my blog.
You get that serialization error because DevForce can't find your entity model while in the designers. I don't know yet why we can't find it and I'm going to get to the bottom of that question. Meanwhile, the workaround is simple: tell DevForce where to find your model assembly ... which you do with a line such as follows. You must execute it BEFORE creating any EntityManager:
// Register the model's assembly name among probed assemblies // Must be called BEFORE the first EM creation else // fails w/ deserialization exception IdeaBlade.Core.IdeaBladeConfig.Instance.ProbeAssemblyNames .Add(typeof(BookClubEntities).Assembly.FullName);
The "BookClubEntities" class happens to be the specialized EntityManager defined in the application model; any class from that model would do for finding the model assembly.
Edited by WardBell - 05-Dec-2010 at 11:25am
|
 |
WardBell
IdeaBlade
Joined: 31-Mar-2009
Location: Emeryville, CA,
Posts: 338
|
Post Options
Quote Reply
Posted: 02-Dec-2010 at 1:50pm |
|
Mike - I am at Firestarter today so can't look at it this second. I take it you are not creating and attaching entities in code but, rather, trying to import them into the Design Entity Manager cache. I will look at this when I get back.
|
 |
mikedfox
Newbie
Joined: 29-Apr-2010
Posts: 21
|
Post Options
Quote Reply
Posted: 02-Dec-2010 at 12:50pm |
Ward, this still seems to be broken. I'm adapting your recent clientui example and when I try to add items to my design time data manager using load cache, I get an error in serialization. It says that there are unknown types. At runtime, the same load from cache works.
As an alternate, I tried manually creating some sample data, but get an error trying to add entities with an identity key. Its looking for an idgenerator, even though at runtime it works.
I have 6.0.6.1
|
 |
WardBell
IdeaBlade
Joined: 31-Mar-2009
Location: Emeryville, CA,
Posts: 338
|
Post Options
Quote Reply
Posted: 02-Sep-2010 at 7:54pm |
Update: We reproduced your case, found the obstacle to deserializing the cache while in Blend or Cider, and we have a fix. Unfortunately, the obstacle remains in 6.0.5.
I'm hoping myself to get an early 6.0.6 to try out the fix. Perhaps you can wait another 6 or 7 weeks for the official 6.0.6 ... although I'll be happy to send you an EAP of 6.0.6 as soon as we feel even slighly comfortable with it.
Thanks for driving hard on this issue. That just makes the product better.
|
 |
WardBell
IdeaBlade
Joined: 31-Mar-2009
Location: Emeryville, CA,
Posts: 338
|
Post Options
Quote Reply
Posted: 01-Sep-2010 at 1:31am |
Hi Jason - I did look into it ASAP. The kiosk app I demonstrated at DevConnections in April only works because I can save to cache and restore from cache.
Now that app did not work in design mode at the time because there were gremlins in VS and Blend and in DevForce that worked against it. I must have missed the "design mode" component of your post. It would help if you said "Blend" a few hundred more times so I wouldn't miss it :-)
I haven't had time to see if there are challenges going the next step and working with cached data in a design time VM consumed in Blend (or Cider).
I've been living in 6.0.5 for what seems like forever (6 or 7 weeks is "forever" around here) so I'm not sure if the version upgrade will relieve your troubles.
If you have something that fails, I'd be happy to check it out. Can you send me a small Northwind example? I'd be much obliged. Otherwise, I'll have to put this off for at least two weeks.
p.s.: trust the move went well and you haven't locked yourself out of the house yet.
|
 |
jsobell
Groupie
Joined: 02-Apr-2009
Location: Australia
Posts: 80
|
Post Options
Quote Reply
Posted: 01-Sep-2010 at 12:28am |
|
Sorry, been moving house over the weekend so haven't been coding for a few days...
Not quite sure about this comment:
Hmmm .... we will look into this ASAP. The code snippet I gave you USED to work (6.0.3) but I haven't tried it recently. Maybe something happened. Will follow up. Didn't want you to feel lonely meanwhile.
Which code snippet are you referring to? The snippet you posted only saves the mock data, and there's no problem there; it's recreating the cache in design mode that breaks with internal null reference errors in all the tests I've done.
I'll check out the proper 6.05 when it's online, and see if anything has been magically fixed.
Cheers, Jason
|
 |
WardBell
IdeaBlade
Joined: 31-Mar-2009
Location: Emeryville, CA,
Posts: 338
|
Post Options
Quote Reply
Posted: 25-Aug-2010 at 11:33am |
|
So ... if you still think you're following the recipe and it still isn't working for you ... even with fresh DF 6.0.5 bits ... maybe you can code a little Northwindexample of what you are doing? That's something we could sink our teeth into. Thx.
|
 |
WardBell
IdeaBlade
Joined: 31-Mar-2009
Location: Emeryville, CA,
Posts: 338
|
Post Options
Quote Reply
Posted: 25-Aug-2010 at 11:17am |
Perhaps you may take some comfort in this: I just ran the code and application from which I took that extract (above). Ran it on the nearly latests 6.0.5 bits ... after deleting old test data file and reconstructing ... and it all works ... on my machine :-)
That doesn't make it work on yours of course. At best it indicates that the process works SOMEWHERE on SOME VERSION of DevForce.
Please check again that you are constructing the cache file with a Silverlight application.
In early days, I tried to create the cache file with a Desktop client. I got the similar serialization failures. You have to build the cache file in an SL "DataMaker" app referencing the same Silverlight model that you will consume in your SL production app.
You probably are doing exactly what I just said ... but I think it worth emphasizing because it is so easy to miss this distinction and sink into the morass (as I first did months ago).
|
 |
WardBell
IdeaBlade
Joined: 31-Mar-2009
Location: Emeryville, CA,
Posts: 338
|
Post Options
Quote Reply
Posted: 25-Aug-2010 at 9:11am |
|
Hmmm .... we will look into this ASAP. The code snippet I gave you USED to work (6.0.3) but I haven't tried it recently. Maybe something happened. Will follow up. Didn't want you to feel lonely meanwhile.
|
 |
jsobell
Groupie
Joined: 02-Apr-2009
Location: Australia
Posts: 80
|
Post Options
Quote Reply
Posted: 24-Aug-2010 at 6:14pm |
|
Hi Ward,
The generation and inclusion of the mock data in my test follows the
same approach as yours, and I also include the mock data as a resource. I
don't have any issue with this approach.
The code for restoring the cache is where my experiment fails:
var xx = new RiskStructureDB();
xx.DefaultQueryStrategy = QueryStrategy.CacheOnly;
Stream stream = Application.GetResourceStream(new
Uri(@"RiskStructureEditor;component/MockData/mock.bin",
UriKind.Relative)).Stream;
xx.CacheStateManager.RestoreCacheState(stream, RestoreStrategy.Normal, true);
This fails in 6.0.5 with the following exception:
at IdeaBlade.EntityModel.DataSourceResolver.FindKey(String keyName, String keyExtension)
at IdeaBlade.EntityModel.DataSourceResolver.BuildRelatedInfo(String dataSourceKeyName, IIdGenerator idGenerator)
at IdeaBlade.EntityModel.DataSourceResolver.set_DataSourceInfoMap(Dictionary`2 value)
at ReadDataSourceResolverFromXml(XmlReaderDelegator ,
XmlObjectSerializerReadContext , XmlDictionaryString[] ,
XmlDictionaryString[] )
at
System.Runtime.Serialization.ClassDataContract.ReadXmlValue(XmlReaderDelegator
xmlReader, XmlObjectSerializerReadContext context)
at
System.Runtime.Serialization.XmlObjectSerializerReadContext.ReadDataContractValue(DataContract
dataContract, XmlReaderDelegator reader)
at
System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator
reader, String name, String ns, DataContract& dataContract)
at
System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator
xmlReader, Int32 id, RuntimeTypeHandle declaredTypeHandle, String name,
String ns)
at ReadEntityCacheStateFromXml(XmlReaderDelegator ,
XmlObjectSerializerReadContext , XmlDictionaryString[] ,
XmlDictionaryString[] )
at
System.Runtime.Serialization.ClassDataContract.ReadXmlValue(XmlReaderDelegator
xmlReader, XmlObjectSerializerReadContext context)
at
System.Runtime.Serialization.XmlObjectSerializerReadContext.ReadDataContractValue(DataContract
dataContract, XmlReaderDelegator reader)
at
System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator
reader, String name, String ns, DataContract& dataContract)
at
System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator
xmlReader, Type declaredType, DataContract dataContract, String name,
String ns)
at
System.Runtime.Serialization.DataContractSerializer.InternalReadObject(XmlReaderDelegator
xmlReader, Boolean verifyObjectName)
at
System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator
reader, Boolean verifyObjectName)
at System.Runtime.Serialization.XmlObjectSerializer.ReadObject(XmlDictionaryReader reader)
at IdeaBlade.EntityModel.SerializationFns.RestoreDCS(Type
instanceType, Stream stream, Boolean closeOnExit, IEnumerable`1
knownTypes)
at IdeaBlade.EntityModel.EntityCacheState.Restore(Stream stream, Boolean closeOnExit)
at IdeaBlade.EntityModel.CacheStateManager.RestoreCacheState(Stream stream, RestoreStrategy strategy, Boolean closeOnExit)
at RiskStructureEditor.MainPageModel.LoadCacheState() in
C:\Dev\RiskStructure\Silverlight\RiskStructureEditor\RiskStructureEditor\MainPage.model.cs:line
350
This appears to be related to the old issues of the DataSourceResolver serialization etc.
Any suggestions? Once I get the cache retrieval working I'll happily join you in finding an elegant application of this approach :)
|
 |
WardBell
IdeaBlade
Joined: 31-Mar-2009
Location: Emeryville, CA,
Posts: 338
|
Post Options
Quote Reply
Posted: 24-Aug-2010 at 10:10am |
|
@jsobell I invite you to improve this approach and share with the rest of us!
|
 |
WardBell
IdeaBlade
Joined: 31-Mar-2009
Location: Emeryville, CA,
Posts: 338
|
Post Options
Quote Reply
Posted: 24-Aug-2010 at 10:04am |
Glad to hear it's working for you. 6.0.4 made a big difference in this regard.
Not sure how quickly I can get to the example you want so let me give you some hints.
You have to create the cache file from within a Silverlight Client. You'll be working with SILVERLIGHT types in your SL app so you have to populate your cache with the entities defined as the Silverlight types.
Here is an extract from actually working, code-behind of a tiny SL app called KioskTestingDataMaker:
using System; using System.Windows; using System.Windows.Controls; using System.IO;
namespace Kiosk.Testing.DataMaker { public partial class MainPage : UserControl { public MainPage() { InitializeComponent(); } private void HandlePageLoaded(object sender, RoutedEventArgs e) { DataMaker = new TestDataMaker(); DataMaker.ReadyToWrite += EnableSaveButton; DataMaker.Build(); } private void EnableSaveButton(object sender, EventArgs args) { saveButton.IsEnabled = true; statusTB.Text = "Cache data is ready; click SAVE button to save to local file system."; } private void HandleSaveButtonClick(object sender, RoutedEventArgs e) { statusTB.Text = "Save to the file named "+ DataMaker.CacheFileName + " in the directory 'Kiosk.Model.Testing.SL'." ; OpenSaveFileDialog(); } private bool OpenSaveFileDialog() { SaveFileDialog sfd = new SaveFileDialog() { DefaultExt = "dat", Filter = "Data files (*.dat)|*.dat|All files (*.*)|*.*", FilterIndex = 1 }; if (sfd.ShowDialog() == true) { statusTB.Text = "Saving cache data to " + sfd.SafeFileName + " ... please wait for next message ..."; using (Stream stream = sfd.OpenFile()) { DataMaker.WriteCacheToStream(stream); stream.Close(); } statusTB.Text = "Saved test data to " + sfd.SafeFileName + " ... You're done ... close the application."; return true; } statusTB.Text = "You cancelled ... cache data was not saved; you may close the app now." ; return false; } private TestDataMaker DataMaker { get; set; } }
The XAML that goes with it has a Save button and a TextBlock to show the instructions. Dumb and ugly as it comes.
I leave as an exercise for you the implementation of the class called TestDataMaker. It's primary job is to query for the entities you want for your test into its EntityManager.
The TestDataMaker app asks the user to identify where the file should be saved. That is because this app is a browser-based and must ask for permission. Were it out-of-browser with elevated permissions, it might do this without asking; I wrote this for SL 3 before elevated trust existed.
The next challenge is to find and read the cache to load your test- or design-time EntityManager. I imagine there are many ways to do this. What I did was save the file to one of my Silverlight Testing projects. Everytime I run the DataMaker it replaces that file. Meanwhile, that file has a build action of 'Resource" in the test project. Resources are easy to read in Silverlight so my TestRepository has no trouble streaming in the Resource and loading the test EntityManager.
You see the "write" side of this equation in the code above where I ask the user to save the file to a file with the name give by the DataMaker.CacheFileName property (e.g., "TestDataCache.dat"), located in the local file system folder, "Kiosk.Model.Testing.SL".
Finally, you have to remember to rebuild the Kiosk.Model.Testing.SL test project so that it incorporates the revised resource file.
The whole process is more baroque and manual than I would like. Fortunately, I don't have to re-make the test data very often. I can live with it.
Btw, note that the resource file is checked in with the project ... so I've got my test data under source control :-/
HTH
|
 |