Silverlight design time error using VS 2010

Silverlight design time error using VS 2010

Old forum URL: forums.lhotka.net/forums/t/9062.aspx


mbianco21 posted on Thursday, June 10, 2010

Using CLSA 3.8.3, VS2010, .NET 3.5, SL 3.0. I am getting the following error in design time only. Help!

P.S. I will get this error in Blend 3, but not in VS 2008.

RockfordLhotka replied on Thursday, June 10, 2010

It looks like your data access code is being invoked when the designer loads some part of your UI. That's not uncommon - the XAML designers create instances of UI types, which might create an instance of your viewmodel or business object. In the end, your factory method is being called.

Of course you have no config file for blend, so the data portal is unable to find your app server and/or database.

You need to block the factory method from being called, or make the factory method not do anything - when the code is running in design mode.

mbianco21 replied on Thursday, June 10, 2010

That makes sense. It is the "how to" part I was after. In the snipet below, is there anyway to check whether I am in design mode in the xaml and switch the IsInitialLoadEnabled to false? (Which solves the problem). Aren't others having this problem? I am following a pretty basic and common pattern I learned from the video series. Any recommendation would help. Thanks in advance.

       <csla:CslaDataProvider 

                               x:Name="FSAListProvider"

                               ObjectType=Business.FSAList, Stock.Business"

                               ManageObjectLifetime="True"   FactoryMethod="GetFSAList"  

                               DataChangedHandler="{StaticResource DataErrorDialog}"

                               IsInitialLoadEnabled="True"  >

mbianco21 replied on Friday, June 11, 2010

Okay. This is what I came up with- at least for the time being (and I can get back to work). This is on the client....If anyone has something better, I would love to hear...

        public static void GetFSAList(EventHandler<DataPortalResult<FSAList>> callback)

        {

            if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(System.Windows.Application.Current.RootVisual))  {

                var dp = new DataPortal<FSAList>();

                dp.FetchCompleted += callback;

                dp.BeginFetch();

        } 

        }

   }

RockfordLhotka replied on Friday, June 11, 2010

Now that I'm home and have a couple minutes, I can provide a little more background.

Prior to 3.8.2 the data portal did this check for you, and routed data portal calls to a "design time create/fetch method".

There were two problems with that.

  1. There's apparently a SL/.NET runtime bug that causes this to fail with a Win32 exception under high load (that's really bad)
  2. VS 2010 has a different way of handling design time data

CSLA 4 entirely eliminates the design time concept - since there's this new model.

CSLA 3.8.2 has a quick fix that eliminates the design time check to avoid the runtime issue that several people had encountered - it just never detects that the code is in design time...

The drawback is that you end up having to handle it yourself. The benefit is we avoid issue #1.

However, you should probably wrap your design time check code in "#if DEBUG" blocks, so that code doesn't get compiled into your deployed code (which would be release mode of course) - otherwise I suspect you run the risk of encountering the same runtime Win32 error.

Finally, and you probably won't like this, the whole data provider model appears to have lost support from Microsoft. Not that they are removing the feature, just that they aren't using it - which means it is effectively legacy technology. Instead, you are probably better off looking at the MVVM design pattern and using a viewmodel instead of a data provider.

CSLA 3.8 and higher has a ViewModel<T> base class that gives you a viewmodel with most of the functionality of the data provider - so the switch isn't too bad - but it is a slightly different architectural choice. The benefit of a viewmodel is that you write the constructor, which is where you invoke the factory method of the business type - so you can keep the design time check in the viewmodel (which is part of the presentation layer), and avoid having a WPF/SL-specific check in your business layer.

Architecturally, it is really terrible to put the design time check in the business class - but when using the data provider there's no good way to move it out, while with a viewmodel there's a good answer.

mbianco21 replied on Tuesday, June 15, 2010

Thanks Rocky, appriecitate it. Hello viewmodel!

ajj3085 replied on Tuesday, June 15, 2010

I do have a question about this, several really.

First, at my new gig, we are doing a lot of stuff I haven't done before, namely mocking and ICO for tighter unit tests.  Static factory methods can't be mocked away.  For a PoC I've been working on, I just created a factory object to wrap the call to the static method.  Not quite sure if that's the proper solution.  What are others' consensus on this when unit testing the view model? (I assume you'd want to, as there we have had good results unit testing the controller in MVC).

Second, won't the data access run this way when working with the designer, since it will create a view model?  I know I've hit wierd exceptions in the 2008 Wpf "designer" which turned out to be exceptions thrown when the dataportal didn't work properly (because the database connection wasn't available).  Am I missing something, or do you still have to consider this?

Thanks

Andy

Copyright (c) Marimer LLC