I was impressed with Nathan's reflective textbox in Avalon. I wanted to improve on his sample and make the reflection 3D. The same opacity gradient applies, but this time the VisualBrush is used on a material on a 3D surface. The 3D surface also needs to align itself underneath the TextBox.
See the entire post at my DevAuthority blog entry.
I took up Dave Balzer's invitation and decided to move over to DevAuthority. I just wanted to extend my thanks to Donny and the gang here at DNJ.
I will continue to cross-post for a while.
A little while ago I came up against some performance problems in a mixed Managed/Unmanaged C++ assembly. I decided to profile the code and found that it wasn't as I had expected. The functions in unmanaged code, and even the functions from a vendor C++ API, were all appearing as managed .NET functions.
Complete entry over at my blog at DevAuthority.
It's all very nice, with the channel 9 video and blog entry, using RSS as a standard method to do polymorphic vector persistence is a nice touch. Here are some observations on the video:
First off, before everyone gets excited about 'RSS for the masses' and using a subscription model will be the 'new standard way of browsing the web'. It's worth thinking back to around 1996 when IE and Netscape were rushing the 'push' model to the market. Back then it was called 'channel subscriptions' but it never really caught on. I think this will be more successful, but it's worth keeping in mind why the 'channel push' didn't work last time round for the average user. I blame lack of adoption, on demand connections and a general bad implemention on the user interface.
The team kept mentioning that the 'glue applications' that they used to pull together these feeds were all written in C#. I think we can assume that this RSSimplement ion toolkit is going to be a .NET assembly. I won't be the only one hoping that this means that IE7 will *depend* on .NET 2.0. This will make the download huge of course, but it makes perfect sense to pay this price now and make the download for WinFX runtime in the future less than 100MB.
If you think about it, IE7 is the perfect deployment vehicle. For the tech savvy, with broadband connections, the large download will not be a problem. For the general public, who really don't care which version of IE they have, will get their version through the mail from their ISP or on a cover disk on a magazine.
For the .NET world the lack of installed base is a big issue. With users taking a long time to upgrade their OS, Longhorn is too far out. Given that Avalon and Indigo are based on the same runtime as Whidbey, which is being released in November, it makes a lot of sense to get this version on as many desktops as possible.
There are a lot of changes to Collections in Whidbey. I'll highlight some of the changes here:
The generic interface IList can be used to house any collection, including arrays.
IList<string> stringList = null;
string[] stringArray = new string[] { "one", "two", "three", "four" };
stringList = stringArray;
IList includes methods for removing and adding, but these are invalid when the IList points to an array. To check if you can manipulate the IList there's a IsReadOnly property:
if (stringList.IsReadOnly)
{
Console.WriteLine("Readonly");
}
The List<> collection can be used like ArrayList. In this case we create a new collection based on our array. The List<> can be manipulated.
stringList = new List<string>(stringList);
if (!stringList.IsReadOnly)
{
stringList.RemoveAt(0);
Console.WriteLine("Can modify");
}
Another cool new feature is the ForEach method. The example below uses ForEach and an anonymous delegate to set-up a dictionary from the contents of our list. IList<> doesn't support ForEach, only the List<> class supports it.
List<string> stringList2 = new List<string>(stringList);
string oneString;
IDictionary<string,string> stringDictionary = new Dictionary<string,string>();
stringList2.ForEach(delegate(string item) { stringDictionary.Add(item, item); });
Another cool feature is the ability to test for an item in a dictionary and return it in one go. This is much more efficient than doing the double look-up in .NET 1.1:
if (stringDictionary.TryGetValue("two", out oneString))
{
Console.WriteLine("Got value in one go " + oneString);
}
This one is simple, it allows you to test for null or empty strings in one static function:
string s = null;
string s2 = string.Empty;
string s3 = "";
if (string.IsNullOrEmpty(s) && string.IsNullOrEmpty(s2) && string.IsNullOrEmpty(s3)) Console.WriteLine("Works");
This is more for convenience than anything else.
I thought I'd blog about some of the less talked about new features in VS 2005.
This one is in the C# language - I discovered it at the C# SDR during one of the demos. It can be best summarized as follows:
Old method:
object result = GetResult(); // return some object, that can be null
Console.WriteLine( result==null ? “NULL” : result ); // write 'NULL' if the returned value is NULL, otherwise just write ToString()
New method:
object result = GetResult(); // return some object, that can be null
Console.WriteLine( result ?? “NULL” ); // syntax is abbreviated, result is used unless the value is null - otherwise the value after '??' is used.
This operator becomes very useful when using nullable types:
int? result = GetResult();
int total = 300;
total = total + result; // ! compiler error - cannot add a nullable int to a non-nullable int
total = total + result ?? 0; // Correct usage - result defaults to 0 if null
The redist
here and the SDK is
here.
There's a couple of great posts on Channel9.
First off a really good Avalon demo, the first one that I've seen demonstrating video feeds as textures. The impressive Amazon front-end app is there as well. Roll on the next CTP.
More importantly is the interview with Jim Allchin. We finally have confirmation that Avalon is at the heart of Aero. This was previously unclear, with comments from Chris Anderson implying that Aero could be something separate altogether. I think we wanted some clear signs that Avalon was a key part of the OS.
I've just got back from a couple of days at Redmond, attending the C# SDR. The presentations were very interesting and discussions and feedback very vocal. This was my first SDR, so I wasn't too sure what to expect.
Unfortunately, most of the topics aren't public yet... so nothing really to post, tech wise.
Big thanks goes to Dan, Luke & co for making us feel welcome.
My last post seems to have caught the attention of a few.
From what Scoble and others have said it sounds like Aero is not what we were expecting. Here's my thoughts:
- Aero is the name of the UI in Longhorn, previously presented as a UI that takes advantage of the GPU.
- Therefore Aero cannot be based on GDI, why invest a whole new windows interface on a API that will soon be obsolete?
- Aero must therefore be based on DirectX / WGF etc...
- If Aero itself isn't written as managed code, there must be at least some .NET hosting at the very least. If not then this will be seen as a lack of confidence in the .NET platform.
- If Avalon (and therefore WinFX) is just going to be 'on the same disk' as Longhorn then this still raises the question of deployment. Why not make this a mandatory install ? Who is going to write an Avalon 'smart client' if they think that it's going to come with a hefty install of the WinFX runtime.
I still remember when we were being told that all the new APIs in Longhorn were managed APIs. I wonder if this is still the case? If Aero uses WGF then what is Aero? Does it include config apps like Control Panel? I'm starting to suspect that Aero is just an interface on top of the normal Windows Manager - like Windows Media Center for the desktop.
My concern is that there is a lot of Avalon development going on out there, under the original premise that come 2006 there will be a new OS with Avalon ready installed. Since then we had the good news that this will also run on XP. But, if Avalon is only an optional component on Longhorn and a 60MB download on XP then the target user base is somewhat smaller than first promised. If there's a change in the plan then this sort of change of policy should really be made public ASAP.
Over on The Server Side.NET there's an interview with Chris Anderson about Avalon. One thing that struck me as strange is the part (talking about shipping Avalon) where he said:
And that is scheduled to ship as part of Longhorn right?
That's scheduled to ship simultaneously with Longhorn and I believe right now the plan is for it to be on the disc with Longhorn.
'On the disc' with Longhorn. Surely Aero, the new shell in Longhorn, depends on Avalon and therefore Avalon is a must install with Longhorn? Maybe Aero is now being shipped as part of the Avalon download - a way to get WinFX out to as many desktops as possible. One less reason to upgrade to the new OS. I always thought of Aero as one of few remaining carrots that Longhorn was tempting users with.
Anyway, nice to see somebody using the UK spelling of 'disc'.
I'm always trying to maximize the amount of visible code that can fit on a screen at one time. I think this improves the ability to cross reference calls and evaluate logic etc.. One annoying feature of the VS.NET is the way the <summary> tag takes up at least three lines when really it could just append everything onto one line. So...
<summary>
My comment
</summary>
could be
<summary>My comment</summary>
To do this I just do a Find and Replace with a regular expression. The Find String is:
\<summary\>.*\n:b+///:b{.*}\n:b+///:b\</summary\>
And the replace string uses the tag above (in curly brackets):
\<summary\>\1\</summary\>
One thing that is strange, why does VS.NET use a different tagged expression syntax to System.Text.RegularExpression?
In my previous post I went through a basic outline of how I've performed OX mapping to C# classes. In reality getting this mapping correct will always be impossible. The reason is simply that they are too different. On one side a programmatic class or ADT has always represented memory with a type safe abstraction. On the side in the messaging world, a message and its schema describe what is valid for a series of bytes over a stream. One implies complete random access, using names to uniquely identify memory locations. The other aims to describe what to expect during the course of a conversation with a connected process.
The two goals make the two modeling approaches very different. In a message schema you can have optional elements, anonymous types and repeated elements with the same name. You can also have elements that are undefined, that can contain any element. There are a number of approaches used to solve this design gulf:
- Use messages only, don't do OX mapping. Some people suggest that we shouldn't even try to map messages to classes and that web services should not be treated as API calls because they are not. Realistically, developers gravitate towards achieving their goals using the simplest method. It's very unlikely that you will find your average Visual Basic developer dealing with asynchronous communications and parsing XML. In all but the most trivial processes this data will need to be mapped to classes or structures eventually, unless web service developers are willing to give up type safety.
Something that the message advocates also ignore is performance. Performing a one time mapping to actual classes (as in XML Deserialization) has the potential to be a lot faster than creating an XML DOM and reading that DOM structure for all your processing.
- The next option is to restrict XML schemas to configurations that are compatible with simple OX mapping. Like the DataSet schemas in .NET, using special schema formats you can achieve good OX mapping and equate classes to XML types across platforms. The problem is, who will define these standards? Who will buy into this standard, some message oriented folks may stick with the complete schema. Something like this is already happening and causing problems with developers creating services that return Typed Datasets.
- Change the language - improve the language to support more abstract definitions of what a class/struct can be. If the language can support all the features of the message schema then in theory the mapping will be trivial. This is how we arrive at COmega (check the MSDN article here, or a nice summary here).
COmega was developed by MS Research and (like generics before it) it looks like it could get integrated into the runtime itself. In fact Anders Hejlsberg was interviewed on Channel9 saying that “tighter integration with data” was what they have in mind for C#3.0. If you read the comments below the video there are some strong indications that the extensions to C# that COmega presents could end up as part of the CTS.
If this does happen then the implications are massive. .NET would become the preferred platform for speaking XML. The next version of Indigo could make good use of this, providing the developer with a true picture of what inbound messages and outbound messages really contain. The XML experience in a .NET language would be far superior than any other.
To make this leap wouldn't be easy and some big changes in the type system would be required. Some of these changes may not sit well with other .NET languages - potentially a much larger change than the inclusion of generics.
In my previous entry I went through the what's and why's of mapping XML Schema to classes. I'd like to use this post to outline the rough algorithm of how I've tackled this mapping, it may be useful for other people to compare their implementations. Also, with Indigo coming along soon it will be interesting to see how OX Mapping is implemented using this new technology.
The basic mapping is quite simple, the rules are as follows:
- Each element with a complex type in the schema maps to a class.
- Each simple type element belonging to a complex type is a property on that class.
- Each nested complex type element has an implicit one-to-many relationship with the parent element.
- Where minOccurs=0 the property is optional.
- Where maxOccurs>1 the property should be defined as an array.
- For each relationship the class should contain access methods or properties. For relationships where maxOccurs>1 the class should have a method that returns an array of the mapped type, where maxOccurs=1 it should be a property. The relationship should be bi-directional with an access property for the parent.
- Where maxOccurs>1 a collection should be defined to house the complex type element. This collection should include helper functions to access elements using indexes defined using constrains and keys in the schema.
- Enumerated facets should be translated to enumerated types in the code.
- You should be able to define explicit constraints that include relationships between elements.
This is basically what the XML Typed DataSet Generator is doing. The DataSet prefers a specific format of schema, but the basic premise is there. Of course these aren't all the rules, there are plenty more.
It all becomes more complicated when you introduce derived schemas. If a given schema contains complex types that reference other complex types, maybe from other schemas then the OX Mapper can be implemented in two ways. It can ignore the derivation information and just generate a flat class or it can take the derivation information from the schema and generate equivalent classes in the code. This will allow the class user to keep a polymorphic relationship with other derived schemas else where in the system.
The process could work like this:
- If a new element contains a complex type that derives from another complex type the base class is defined as any element that implements the base type. If the base type is defined in a different schema then the element should be defined in that schema.
- If the relationship and index features of the base type need to be preserved and used in the derived type then a 'replacement' schema should be used rather then normal complex type derivation. Using a replacement the existing element is modified and the existing constraints still apply.
- If only new constraints need to be added to an existing element (an existing class from another schema) then the type does not need to be derived and only new constraints are required to be added at the parent element level. This can be done using a replacement schema and modifying the parent element.
The problem is that now the derived types need to be compiled in with the assembly for the names to be resolved. This may require an additional step where another OX Mapping process needs to import the base schema(s). The actual process is more involved and many of the problems stem from the necessity to include constraints as part of the interface on a class. Without this requirement the whole process would be a lot easier.
So - is this really worth spending much time on? If you were creating an SOA infrastructure for your clients, or internally in your department you would want to model your complex types with re-usability in mind. With this re-usability you would want to development a base core model and maybe derive complex types for specific vertical applications using them. You would also want to interoperate these types at the code level, if you wanted to make use of re-usable libraries. The bottom line is that you would really want your typed universe in the WSDL/XSD world to map to the typed universe in the .NET world of shared assemblies. If you want all this then your OX Mapper wil