Working Around BehaviorNotImplementedException When Instantiating Stubs

I got this exception in this morning, but thankfully there is a workaround. Do not despair!

Assume the following code. In the Concrete class we have a global level _internalString field and the virtual TestString property with returning the string literal “Pex Is Pissing Adam Off!” (as it was this morning!) in the Concrete base class constructor we are simply backing field settings, nothing amazing. Yeah the virtual member call in the concrete class constructor is bad since it will cause the most derived override to be called, even though the most derived constructor has not been fully run yet (may not be in a suitable state to have that method called). But bah! It’s part of the code and it’s not like that warning isn’t already thrown in nearly every SharePoint artifact.

Anyways, so in the rest of the code there is nothing amazing that is happening, as you can see the class containment hierarchy is using the Concrete base class for the child Superclass derived class, which is just overriding a simple property.

[csharp]
namespace AdamHatingPex
{
public class Concrete
{
private string _internalString;
public virtual string TestString{ get { return “Pex Is Pissing Adam Off!”; } }
public Concrete()
{
_internalString = TestString;
}
}
public class SuperClass : Concrete
{
public override string TestString
{
get { return “But I’ll Get Over It”; }
}
}
}
[/csharp]

Assuming this code, if you stub out the derived class you are going to get a Microsoft.Moles.Framework.Behaviors.BehaviorNotImplementedException error, as you can guess since it’s the only thing in the class it occurs on the overridden property. Quick hint, using CallBase with your call won’t help since base constructors should be run before derived ones (going back to what was discussed previously).
However, it is solvable by changing the behavior. I am not going to get into behaviors yet but you can adjust behavior pre-instantiation of the stub and let it Fall Through or Default Provide A Value. By default the instance will use the BehavedBehaviors.Current property, which will by default throw a BehavedBehaviors.NotImplemented. You can switch this around by setting the InstanceBehavior property on any stub instance. This is pretty easy, demonstrated below:

[csharp]
BehavedBehaviors.Current = BehavedBehaviors.Fallthrough;
var x = new Test.Moles.SSuperClass();
[/csharp]

When you are done with your stuff, you can return to default behavior:

[csharp]
BehavedBehaviors.Current = BehavedBehaviors.NotImplemented;
[/csharp]

If you are interested in this, you should look into the [assembly: PexChooseAsBehavedBehavior] attribute further as well.

Share

Fix Unhandled Error in Silverlight 2 Application Invalid cross-thread access error

Had a support call from a client today regarding a problem them were running into with Client OM access from a Silverlight application. The exact error was “Invalid cross-thread access”. Sitting down with the developer at the site I determined that this problem can be caused by two issues:

1) Your XAP is not copied into the right location. It is supposed to go into the 14 hive ClientBin directory under LAYOUTS. If the XAP is not present, this error can occur.

2) Objects in code and not being loaded correctly (this turned out to be the primary issue for my particular problem). Consider the following simply ListItem update code:

[csharp]
private void UpdateData()
{
ClientContext clientContext = new ClientContext(“url”);
Web web = clientContext.Web;
ListCollection listCollection = web.Lists;
list = listCollection.GetByTitle(“TestList”);
ListItem li = list.GetItemById(1);
li[“Title”] = “My new item”;
li.Update();
clientContext.ExecuteQueryAsync(onQuerySucceeded, onQueryFailed);
}

private void onQuerySucceeded (object sender, ClientRequestSucceededEventArgs args)
{
// I am not displaying show ShowMessage, but assume that it writes the list title to standard output
UpdateUIMethod updateUI = ShowMessage;
this.Dispatcher.BeginInvoke(updateUI);
}

private void onQueryFailed (object sender, ClientRequestFailedEventArgs args)
{

}
[/csharp]
Now, looking back at the error, what’s missing in the above code is the load! The objects will not be initialized with this code, which can cause that particular error.
To fix it, include the load, such as (fully qualified instantiation demoed, you would obviously use your own object conventions):
[csharp]
ClientContext.Load(List,
list => list.Title);
[/csharp]
before executing the query, and the error should go away!

Share