Welcome to the .NET Developers Blog
This is an aggregated blog of .NET developers.
If you have a blog about Microsoft, .NET, XAML, WPF, Silverlight, etc... development
add your blog here.
Email me for any suggestions and feedback.
Minh T. Nguyen
|
|
|
Readify Devpods – coming up for air.
Mitch Denny
- Posted 2/9/2010 4:52 AM
|
For the past eight months since taking on my new role I’ve been nearly 100% focused on building our project delivery capability. Readify consultants have always taken lead roles on challenging software projects that adopt the Microsoft platform either in direct engagements with our customers or through our various partners.
Devpods add to our market [...]
|
Code Camp, Bar Camp, Camp Time
Adron Hall
- Posted 2/8/2010 9:39 PM
|
|
The first Code Camp & Bar Camp, which is joining forces, was held tonight. With representatives from Code Camp, Legion of Tech, and the SQL Group Organizers were all on hand to kick off the discussion. One of the primary focus points was, should we have a two day or single day event? It makes me wonder what would be better for a 800 person or so event. Two days better, one day better? Short days, longer days that run until 10pm? What is your take on the matter? More to come later, so keep an eye out for the Code, Bar, SQL Camp Event o' the year!
|
IRIS: ReView Part 2
Steve
- Posted 2/8/2010 5:29 PM
|
|
Well… I promised you a working prototype for Part 2, and here it is! Spent today getting the planned UI completed and actually have almost all the features implemented and working. The coolest part to me is that there is a “Zoom Live” button which launches the Live video feed fullscreen, giving the alarm operator [...]
|
LINQ-Queries dynamisch aufbauen
Martin Hey
- Posted 2/8/2010 1:22 PM
|
Einer der größten Vorteile von LINQ to Objects ist es, dass man typsicher auch sehr komplexe Abfragen über Objektstrukturen durchführen kann. Zuweilen möchte man aber dem Anwender die Möglichkeit bieten, selbst zu bestimmen, welche Operationen mit den Objektstrukturen durchgeführt werden. Als Beispiel soll hier die dynamische Filterung und Sortierung anhand der Member des Objekts dienen. Spätestens zu diesem Zeitpunkt wird eines der größten Pro's von LINQ zum Verhängnis - die Typsicherheit. Um hier eine gewisse Dynamik unterzubringen muss man zunächst wissen, wie LINQ-Queries aufgebaut sind. Sie bestehen aus sogenannten Expression Trees, die dann ausgeführt werden. Liegt ein LINQ-Query vor, kann man sich z.B. mit dem Expression Tree Viewer aus den C# Samples den Expression-Tree ansehen.  Um hier dynamische Filterung und/oder Sortierung zu implementieren, gilt es, einen solchen Baum dynamisch aufzubauen. Das ist gar nicht so kompliziert, wie es sich auf den ersten Blick anhört.  Angenommen, es liegt eine generische List mit Adressen vor (im Beispiel Restaurant-Adressen) - mit den für Adressdaten typischen Membern (Name, Straße, Postleitzahl, Ort). Per Parameter soll definiert werden können, welche Eigenschaft gefiltert werden soll und wie das Filterkriterium ist -gleiches gilt für die Sortierung. Im Beispiel definiert die Klasse RestaurantRepository Zugriffsmethoden für den Zugriff auf Listen vom Typ Restaurant. Dabei kann mittels GetRestaurants eine komplette Liste abgerufen werden die Methode GetFilteredRestaurants implementiert den dynamischen Aufbau. Als Parameter dient hier zunächst ein Dictionary, dessen Key den zu filternden Membernamen und dessen Value den zu filternden Wert beinhaltet - sowie eine Liste, deren Inhalt definiert nach welchen Membern sortiert werden soll.
public static IEnumerable<Restaurant> GetFilteredRestaurants(Dictionary<string, string> filter, List<string> sort) { IEnumerable<Restaurant> restaurants = GetRestaurants();
#region get lambdas // where ParameterExpression pe = Expression.Parameter(typeof(Restaurant), "address"); Expression whereExpression = null; foreach (string filterAttribute in filter.Keys) { Expression left = MemberExpression.Property(pe, filterAttribute);
string filterValue = filter[filterAttribute];
Expression right = Expression.Constant(filterValue);
if (whereExpression == null) { whereExpression = Expression.Equal(left, right); } else { whereExpression = Expression.And(whereExpression, Expression.Equal(left, right)); } }
Expression<Func<Restaurant, bool>> whereCondition = Expression.Lambda<Func<Restaurant, bool>>(whereExpression, new ParameterExpression[] { pe });
var filteredItems = restaurants.AsQueryable().Where(whereCondition);
// order by Expression queryExpr = filteredItems.Expression; string methodAsc = "OrderBy"; string methodDesc = "OrderByDescending";
foreach (string sortCriteria in sort) { var type = typeof(Restaurant); var property = type.GetProperty(sortCriteria); var parameter = Expression.Parameter(type, "p"); var propertyAccess = Expression.MakeMemberAccess(parameter, property); var orderByExpression = Expression.Lambda(propertyAccess, parameter);
queryExpr = Expression.Call(typeof(Queryable), methodAsc, new[] { type, property.PropertyType }, queryExpr, Expression.Quote(orderByExpression)); methodAsc = "ThenBy"; methodDesc = "ThenByDescending"; }
#endregion
return (filteredItems.Provider.CreateQuery(queryExpr)).ToList(); }
Zunächst wird eine ParameterExpression instanziiert. Da Member mit Konstanten verglichen werden sollen, wird für jedes Filterkriterium eine MemberExpression und eine Konstante initiiert. Beides wird mit Expression.Equal verkettet. Mit Hilfe von Expression.And können mehrere solcher Vergleiche aneinandergekettet werden. Ist die Filterung durchgeführt, kann dann noch die Sortierung bearbeitet werden. Auch hier wird wieder eine Expression mit MemberAccess initiiert. Anhand des Wertes kann dann mit Hilfe von Expression.Call die Sortierung durchgeführt werden. Ein kleines Testprogramm zeigt dann, dass der Code auch funktioniert... 
|
F# Discoveries This Week 02/08/2010
Rick Minerich
- Posted 2/8/2010 12:41 PM
|
|
Back again with another F# community roundup. There’s been a ton of great content this week, almost too much. To try to combat this I’ve attempted to sort posts roughly in terms of how interesting I found them. All were worth the read though. Also, I’ll be speaking this Wednesday on F# at the Boston .NET User Group. If you find yourself there, be sure to say hello! Dr. Don Syme is a principal researcher in MSR Cambridge. He has a rich history in programming language research, design, and implementation (C# generics being one of his most recognized implementations), and is the principle creator of F#. Perhaps this post should have gone along with the one about macros and how Lisp is a “programmable programming language.” The common tension in any language or runtime design is how much to build in as primitives and how much to implement as libraries within the language or atop the runtime. Last November at PDC 2009 in Los Angeles I gave a talk on F# for Parallel and Asynchronous Programming. The talk begins by covering basic F# concepts, and then focuses on four challenging issues related to concurrency and the tools F# brings for addressing these - immutability, async workflows, and agents. There is an observable trend in Python programmers that results in a reasonable section of them moving to functional programming languages. This trend is encouraged by the Python language, and has a couple of temporal considerations. Much like C# 4.0 has the ability to do dynamic lookup, F# also has the same capability, although in a different capacity. The language has support for a dynamic lookup get operator ( ? ) and set operator ( ?<- ), but note that I said support and not actual implementation. The actual implementation is up to you and how you want to use it. In the past couple of Monads posts, we’ve talked briefly about the State and Reader Monads and their potential uses and misuses. Before this series completes, I have a few more to cover including the Writer, Continuation and eventually Observable monad. Today, we’ll get started looking at the Writer Monad and what it can do for us. Not all recursive expressions represent recursive behavior. In fact, iteration can be expressed recursively. One trick when considering the process that an expression represents is to think of functions as reducing to values rather than returning them. In a pure functional style (precisely because of referential transparency) you can do analysis by successive substitution. This post describes the F# implementation of the <insert data structure here> from Chris Okasaki’s “Purely functional data structures”. John Conway's Game of Life is a famous example of a simple cellular automaton that produces remarkably diverse results. The game can be implemented in only 32 lines of F# including real-time visualization using Windows Presentation Foundation as follows: Last time I covered IObservables and we created a useful ObservableSource class. Today I’ll cover the next technology piece of the app: reading RSS feeds. I’ll discuss the design considerations regarding how to poll feed for updates and publish feed items as IObservables, and walk through one implementation. A few of my colleagues were discussing F# today and when/where/how it is/isn’t better than C#. I haven’t ever really used F# beyond a very, very brief look at the syntax, so tonight I decided to see what it was all about. As a little project, I decided to make Pong with XNA Game Studio using F# with Visual Studio 2010. If you aren’t excited about new ways to tackle the concurrency problem, or new approaches to handling generic and mathematical problems, and if the thought of breaking out the shiny new lexer and parser don’t give you a tingle, then maybe F# isn’t actually marketed at you at all. Running languages on .NET is ultra-powerful. Using managed COBOL (from Micro Focus), it is possible to use F# code to work with COBOL code. Imagine a Cloud based F# map reduce system consuming legacy COBOL - yes, that really is on the horizon. The new version 0.27 of “FAKE – F# Make” comes with new syntactic sugar for build targets and build dependencies. Don’t be afraid the old version is still supported – all scripts should still work with the new version. Recently I ran into a situation where I needed to handle some events in F# in a special way. In this particular case I wanted to be able to disable and re-enable my handler based on changes in the program. Essentially the C# equivalent of continually adding and removing the handlers. Another bit of spiking, a rather tardy follow up from raw GTK#, starting from the C# example at the Mono Project site, but incorporating the earlier example, so as to build in a clean application exit, for one thing. In this post I'm going to show a small example of taking a picture using a Webcam with Windows Image Adquisition 1.0 . This API seems to have changed in Vista and above, the following code only applies to XP. The article walks through the design and implementation of a multithreaded program that uses logic programming to create an unbeatable computer opponent and Windows Presentation Foundation to provide a graphical user interface in only 115 lines of elegant F# code! OCatenac passes along an interview with Don Syme, chief designer of F#, which is Microsoft Research's offering for functional programming on the .Net platform. Like Scala, which we discussed last fall, F# aims at being an optimal blend of functional and object-oriented languages.
|
Upcoming Events
K. Scott allen
- Posted 2/8/2010 9:14 AM
|
|
Here are some events I’ll be speaking at over the next couple months: Toronto / Mississauga March 8-12. DevTeach stands for Developers Teaching. It’s a conference done by developers for developers. This annual event offers the elements of an international conference and the elements of a community event. Sessions include both presentation material and, whenever possible, hands-on training. We like to describe this event as the Developers Festival. Find out who should attend at this link. Check out the top ten ways to convince your boss to let you go this event. DevTeach is about becoming one of the best developer by getting training from the best in the industry. Göteborg, Sweden March 16-17. Whether you are someone learning development in Java, .NET or IBM i or you are an experienced user of these technologies for 10 years or more, there are lot of great information to be shared with everyone. In addition to technical sessions, we will also have tracks with presentations about the Development Process and Methodology: Agile Methodology, Test Driven Development, System Engineering, Architecture, Project Management, Best practices, "Agile in the Organization". We will also have tracks about hot topics like Cloud Computing, Testing, Web Development and Mobile Solutions. At the Conference there will also be a track of Emerging Technologies presented in cooperation with ThoughtWorks ( www.thoughtworks.com ) DevDays is being held at World Forum in Den Haag March 30-31. DevDays 2010: the biggest Microsoft event in the Netherlands for software development and software architecture. Every year, thousands of professionals visit DevDays to get completely up-to-date with all recent developments in their area of expertise in two days. Las Vegas April 12-14 2010. Developers from around the world will gather at the world famous Bellagio, for the Microsoft Visual Studio Conference & Expo, ASP.NET & Silverlight Conference & Expo and SQL Server Conference & Expo. You can be a part of this exciting event while you enjoy one of the most stunning hotels on the Las Vegas Strip at a great conference rate!
|
Behaviour Driven Development with Cucumber: Video, Slides and Links
gojko
- Posted 2/8/2010 6:08 AM
|
|
Here’s the video from my talk on Behaviour Driven Development and Acceptance Testing with Cucumber last week. In this talk, I go over the basics of Cucumber scenario structure and integration and show examples of using it with Ruby, .NET and Java applications. (scroll down to see the slides and links from the presentation) If [...]
|
Where to find the jQuery 1.4.1 vsdoc file
Jeff Putz
- Posted 2/8/2010 12:40 AM
|
|
If you're like me and you were trying to update your ASP.NET MVC 2 RC2 project with the latest and greatest, and couldn't figure out where the new scripts are, they're here: C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\ProjectTemplates\CSharp\Web\1033\EmptyMvcWebApplicationProjectTemplatev2.0.cs.zip\Scripts That's where you'll find the jquery-1.4.1.min-vsdoc.js file (among others). I'm sure I wasn't the only one scratching my head.
|
Generating Structured Text with StringTemplate
Michael Ceranski
- Posted 2/7/2010 11:45 PM
|
|
StringTemplate is a powerful tool that can be used to generate source code, web pages, emails, or any other formatted text output. Although StringTemplate was originally written in Java it has been ported to C#, Python and Ruby. My first encounter with StringTemplate was a few years ago when I needed to build a complex deployment script for setting up new SQL Server instances. The script needed to configure operators, alerts, SQL mail and also create a few basic jobs. The most important requirement was that the template could be easily changed without recompiling any code or needing any advanced knowledge of programming. Luckily, StringTemplate met all these requirements. In order to get familiar with the functionality lets start by looking at a few sample templates. Here is a classic example which I found on the antlr website. This is a template for generating a simple SQL statement. StringTemplate query = new StringTemplate("SELECT $column$ FROM $table$;");
query.SetAttribute("column", "name");
query.SetAttribute("table", "User");
In this example you probably immediately noticed the dollar signs. When we surround areas of our template with dollar signs we are telling StringTemplate that some work needs to be done. In particular when you execute this code you replace the variable $column$ with the value “name” and $table$ with “User”. The end result is the string “Select name from User”.
Now previously I mentioned that I was using StringTemplate to build a deployment script. In my environment I have many different versions of SQL Server. Since I did not want to write a special template for each SQL version I needed a way to put conditional logic in my template. Fortunately, this is easily accomplished with StringTemplate.
$if(supports_sql_mail)$
...
$endif$
Finally, I also needed a section of my template which created all the various operators in the SQL Instance. Since there are 7 DBAs in my team I needed some sort of loop. Again, StringTemplate to the rescue:
$operators:{
IF EXISTS (SELECT name FROM msdb.dbo.sysoperators WHERE name = N'$it.name$') BEGIN
EXECUTE msdb.dbo.sp_delete_operator @name = '$it.name$'
END
print 'Creating operator: $it.name$';
--create the operator
EXECUTE msdb.dbo.sp_add_operator @name = '$it.name$', @enabled = 1, @email_address = '$it.emailaddress$', @netsend_address = '$it.netsendaddress$', @category_name = N'[Uncategorized]', @weekday_pager_start_time = 80000, @weekday_pager_end_time = 180000, @saturday_pager_start_time = 80000, @saturday_pager_end_time = 180000, @sunday_pager_start_time = 80000, @sunday_pager_end_time = 180000, @pager_days = 0
GO
--notifications
EXECUTE msdb.dbo.sp_add_notification @alert_name = N'Full msdb log', @operator_name = '$it.name$', @notification_method = $notification_value$
... YOU GET THE POINT!
GO
}$
Breaking it down, we define a loop on Line 1. As we iterate over the array, the individual objects are referenced by the keyword it. The properties of each object are read by using dot notation. For example, when I want the operator’s name I use $it.name$.
So by now you have a basic understanding behind the power of StringTemplate. If you want to use StringTemplate in your application there here are the steps:
- Download the binaries (234 kb) from antlr.org.
- Add a reference in your project to the antl.runtime.dll and the StringTemplate.dll.
- Add a using statement for Antlr.StringTemplate.
- Write the code to load the template, and replace the variables.
Now it’s a simple matter of loading the template, substituting some variables and returning the output. Here is the code I used to build my deployment script:
StringTemplateGroup group = new StringTemplateGroup("myGroup", Server.MapPath("/Content/templates/"));
StringTemplate template = group.GetInstanceOf("SQLDeploymentScript");
if ((i.MajorVersion ?? 9 ) >= 9) {
template.SetAttribute("supports_sql_mail", true);
template.SetAttribute("notification_value", 5);
}
else {
template.SetAttribute("supports_sql_mail", true);
template.SetAttribute("notification_value", 4);
}
template.SetAttribute("smtp_server", smtpServer);
template.SetAttribute("mail_account_name", smtpServer + " Administrator");
template.SetAttribute("email_address", "dba@" + instanceName + ".com");
template.SetAttribute("delay_between_responses", delayBetweenResponses * 60);
template.SetAttribute("operators", operators);
return template.ToString();
Breaking it down, on line 1 we define a StringTemplate group. This is basically telling the StringTemplate engine where the templates are stored. Since I am using StringTemplate in web application I make a call to Server.MapPath to get the full directory path. On line 2, we tell StringTemplate that we are going to use the template named “SQLDeploymentScript”. Just to warn you, the filename on disk is actually named SQLDeploymentScript.st but we leave off the extension in our code. This is a convention that StringTemplate uses so just go along for ride. Next, on lines 4-18 we substitute the variables in the template. Finally we call template.ToString() to get the results.
So hopefully this article gave you a good idea of how powerful StringTemplate can be. You can use it to generate HTML, emails, code or whatever else you can dream up.


|
NET Framework 3.5 & NET Framework 4.0
Anand Patel
- Posted 2/7/2010 11:05 PM
|
The .NET Framework is an integral Windows component that supports building and running the next generation of applications and XML Web services. The .NET Framework is hearty of development now & tomorrow for business applications.
Our dot.net consultant hides technical complexity & ensures deliver of better application. Radix has started development on net framework 4.0 to influence best technology for client projects.
Explore technical verticals of Radix consulting & development services from following sections.
|
Keyboard selection on Silverlight ListBox and ComboBox
Fons Sonnemans
- Posted 2/7/2010 12:21 PM
|
|
Silverlight doesn't support keyboard selection on a ListBox or Combox. I have created a small Behavior which fixes this problem. You can attach the KeyboardSelectionBehavior to a ListBox or ComboBox using Microsoft Expression Blend.
Try my behavior below. If you press a key on the ComboBox or ListBoxes it will select the next item starting with the given key.
The ComboBox in this example is not databound, The behavior uses the Convert.ToString() method to convert the Content of each ListBoxItem/ComboBoxItem to a string. An invariant case insensitive StartWith() comparison is used to find the next item.

The left ListBox is databound to SampleData containing Employees. The behavior uses the DisplayMemberPath of the ListBox. The Name of the Employee is used for keyboard selection.

The right ListBox is also databound but has a custom ItemTemplate. The behavior uses the SelectionMemberPath property of the KeyboardSelectionBehavior. The Name of the Employee is used for keyboard selection.

Here is the code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Interactivity;
namespace ReflectionIT.Silverlight.Behaviors {
/// <summary>
/// This behavior can be attached to a ListBox or ComboBox to
/// add keyboard selection
/// </summary>
public class KeyboardSelectionBehavior : Behavior<Selector> {
/// <summary>
/// Gets or sets the Path used to select the text
/// </summary>
public string SelectionMemberPath { get; set; }
public KeyboardSelectionBehavior() {}
/// <summary>
/// Attaches to the specified object: subscribe on KeyDown event
/// </summary>
protected override void OnAttached() {
base.OnAttached();
this.AssociatedObject.KeyDown += DoKeyDown;
}
void DoKeyDown(object sender, KeyEventArgs e) {
// Create a list of strings and indexes
int index = 0;
IEnumerable<Item> list = null;
var path = SelectionMemberPath ??
this.AssociatedObject.DisplayMemberPath;
var evaluator = new BindingEvaluator();
if (path != null) {
list = this.AssociatedObject.Items.OfType<object>()
.Select(item => {
// retrieve the value using the supplied Path
var binding = new Binding();
binding.Path = new PropertyPath(path);
binding.Source = item;
BindingOperations.SetBinding(evaluator,
BindingEvaluator.TargetProperty, binding);
var value = evaluator.Target;
return new Item { Index = index++,
Text = Convert.ToString(value) };
});
} else {
list = this.AssociatedObject.Items.OfType<ListBoxItem>()
.Select(item => new Item { Index = index++,
Text = Convert.ToString(item.Content) });
}
// Sort the list starting at next selectedIndex to the end and
// then from the beginning
list = list.OrderBy(item => item.Index <=
this.AssociatedObject.SelectedIndex ?
item.Index + this.AssociatedObject.Items.Count : item.Index);
// Find first starting with
var text = e.Key.ToString();
var first = list.FirstOrDefault(item => item.Text.StartsWith(text,
StringComparison.InvariantCultureIgnoreCase));
if (first != null) {
// found
this.AssociatedObject.SelectedIndex = first.Index;
}
}
/// <summary>
/// Helper class
/// </summary>
private class Item {
public int Index;
public string Text;
}
/// <summary>
/// Helper class used for property path value retrieval
/// </summary>
private class BindingEvaluator : FrameworkElement {
public static readonly DependencyProperty TargetProperty =
DependencyProperty.Register(
"Target",
typeof(object),
typeof(BindingEvaluator), null);
public object Target {
get { return GetValue(TargetProperty); }
set { SetValue(TargetProperty, value); }
}
}
}
}
You can download the code including the sample application here.
|
Case study of not successful EA practice
Natty Gur
- Posted 2/7/2010 7:45 AM
|
|
After posting three case studies of successful enterprise architecture practices and discussing common EA pitfalls I decided that it’s the time to present a case study of en enterprise architecture practice that didn’t manage end up successfully.
Using Enterprise Architecture for changing business processes
Client environment: The client is a government agency heavily based on information and information management for reaching the agency goals and objectives as they set by the regulator. This client new CEO came with new agenda of how the business need to be done in different and more affective manner. The CEO understands that the best way to enforce his new strategy is by changing IT business applications, systems and technology. To make his vision a reality the CEO asked the CIO to start a group that will make the change in current IT landscape.
Client business goals:
-
Translate CEO vision to practical business capabilities and processes
-
Change IT landscape to support new CEO vision
-
Successfully implement new system to facilitate CEO vision
Approach: the team followed a modeling approach in order to capture current situation, identifying gaps and create migration plan (IT roadmap) to fulfill the above business goals in one year time frame. Using the models we manage to simplify the complexity of the enterprise business, information applications and technology domains and cross relations between those domains. The work has been done internally in the group without interaction with IT teams with a goal to present migration plan after 12 months.
Steps:
-
Translating CEO vision into new set of business capabilities and processes. Using business capabilities to create hierarchal structure of business functionality and by using BPMN describe how those capabilities are being done.
-
Analyzing gaps between current and future business architecture. Understating new capabilities, how business processes are going to be changed and identify new business processes.
-
Mapping current IT assets and modeling conceptual and logical models for Information, Applications and technologies (including hardware).
-
Mapping existing IT assets to existing business capabilities.
-
Based on current IT architecture and new business architecture creating future IT architecture by setting principles, standards, blueprints as well as conceptual and logical models of future Information, Application and Technology domains. The future IT architecture should cover all business capabilities exist in future capabilities map (at least all of the core capabilities).
-
Analyzing gaps between current and future IT architecture.
-
Identify opportunities for each gap and select the best solution.
-
Translate the selected solution into 3 years roadmap.
-
Present the work to CEO and IT.
-
Get CEO support but reluctant approach from IT to adopt the plan.
Conclusion:
although the practice manage to understand new business direction and even get the CEO approve, the practice failed due to the fact that IT didn’t cooperate with the suggested roadmap. The reason for this failure is deeply rooted in the way that the EA work has been done. Doing EA from ivory tower without deep involvement of the people that need to do the work eventually, result in resistant from implementation level and actually caused a failure (regardless if the suggested architecture was the right or wrong one).
|
Setting up SyntaxHighlighter using the hosted scripts
Jon Galloway
- Posted 2/5/2010 3:00 PM
|
|
I’ve tried several source code syntax highlighter systems over the years. Most inserted a bunch of ugly markup and CSS into the page. It kind of worked, but made the “love the web” burst out in tears at inappropriate times. I was really happy to see when Scott Hanselman posted on SyntaxHighlighter, since it seemed to allow for clean markup and unobtrusive Javascript. Here’s the general idea: you set specific classes on an HTML <PRE> tag that contins your code, and the SyntaxHighlighter Javascript and CSS turn on all the magic. So you get pretty code, but it’s still text that can be cut and pasted (as all great code aspires to be). Here’s what it ends up looking like: [TestMethod]
public void AttributesProperty() {
// Setup
DummyMvcControl c = new DummyMvcControl();
// Execute
IDictionary<string, string> attrs = c.Attributes;
// Verify
Assert.IsNotNull(attrs);
Assert.AreEqual<int>(0, attrs.Count);
}
Even better, folks have written utilities to make it easy to insert your code in the correct format for SyntaxHighlighter. My favorite is the PreCode Snippet Manager, which can integrate directly with Windows Live Writer.

Scott summarizes how SyntaxHighlighter works and how you can add the scripts to your site, so I won’t rehash it here.
But what if you can’t (or don’t want to) host the SyntaxHighligher?
So SyntaxHighlighter is great, but what if your blog hosting setup doesn’t let you upload Javascript and / or CSS? No problem, the SyntaxHighlighter site is now offering a hosted version, so all you need to do is link to their hosted files.
For example, here’s how I set that up on my weblogs.asp.net blog (running Community Server 2007). The first trick is knowing where to put custom HTML: the Title, Description, and News area of the management dashboard:

Then you drop in the script references at the end of the News area:

You can use a specific version of the SyntaxHighlighter scripts, or you can use whatever’s the most current. That’ll make sure you get the latest updates, and I think the risk of a breaking change is pretty low. Refer to the documentation on the SyntaxHighliter site for more info, but here’s an example courtesy of Carter Cole:
<link href='http://alexgorbatchev.com/pub/sh/current/styles/shCore.css' rel='stylesheet' type='text/css'/>
<link href='http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css' rel='stylesheet' type='text/css'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCpp.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCSharp.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCss.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJava.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJScript.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPhp.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPython.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushRuby.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushSql.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushVb.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPerl.js' type='text/javascript'></script>
<script language='javascript'>
SyntaxHighlighter.config.bloggerMode = true;
SyntaxHighlighter.config.clipboardSwf = 'http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf';
SyntaxHighlighter.all();
</script> 
|
Wanted: Someone to fix horrendous Graffiti/CS Issues
Sam Gentile
- Posted 2/5/2010 12:24 PM
|
|
My hosting company orcsweb has notified me that Community Server and Graffiti are causing such horrendous issues for their servers that put me on 30 day notice after segregating me to a separate DB server. The average CPU is at approximately 70% with spikes that push it to 100% usage many times throughout the day. I need someone who knows Graffiti to take my Vista DB powered installation and convert it into a SQL Server installation as well as upgrading me to the latest Graffiti as well as Community Server. Also this person would hopefully help track down performance issues. I don't know how much I can pay but I have zero time or knowledge to do this myself Reply here please.
|
DBA Survivor: Name That Caption
Marlon Ribunal
- Posted 2/5/2010 12:09 PM
|
So, the original SQL Batman, Tom LaRock ( Blog | Twitter) , has an upcoming book called “DBA Survivor: How To Become A Rockstar DBA“. Also, I’ve been aware of Tom’s “Name That Caption Contest” over at his book’s website but I never thought of joining the contest until I read Jorge Segarra’s entry. Basically, the contest is [...]
|
Super-simple Object Mapper
Patrick Steele
- Posted 2/4/2010 2:31 PM
|
|
If you need a full-featured object mapper with minimal set up, I recommend you take a look at AutoMapper on Codeplex. If you need a quick-and-dirty solution, maybe the following code could help you out. First off, why am I not using AutoMapper? At my current client, there are strict rules as to the use of open source software. There's a process in place for requesting the use of a particular open source tool, but with the red-tape of the approval process (reviews, signatures, justification, etc…), it could literally take 3 – 6 months. It's just not worth it for what I need right now. So I rolled my own. This mapper is super-simple, not very smart and may have a bug or two in it, but it works for what I need it to do and reduces a lot of hand coding. USE AT YOUR OWN RISK! It uses two simple rules to map data between two objects: - If a property name and type on the source match the name and type of a destination property, the value is copied.
- If the user has defined a custom mapping action, use that to copy data (but rule #1 is always executed first).
Let's dig into the details. First, I set up a generic class that takes in a couple of types – my source and destination types. I added a clause on the destination type that it must be 'new-able' so that I could provide a utility function that would create a destination object, map it's values from a source and return it to you. public class Mapper<TSource, TDest> where TDest : new()
{
}
Copying Properties
When copying data from a source object to a destination object, we get all public instance properties of the destination and see if they have a matching (same name and same type) property on the source. If so, we set the value on our destination object:
protected virtual void CopyMatchingProperties(TSource source, TDest dest)
{
foreach(var destProp in typeof(TDest).GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => p.CanWrite))
{
var sourceProp =
typeof (TSource).GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => p.Name == destProp.Name && p.PropertyType == destProp.PropertyType).
FirstOrDefault();
if( sourceProp != null)
{
destProp.SetValue(dest, sourceProp.GetValue(source, null), null);
}
}
}
Custom Transformations
I want the ability to define my own transformation for special cases. This is simply a list of Action<TSource, TDest> delegates:
protected readonly IList<Action<TSource, TDest>> mappings = new List<Action<TSource, TDest>>();
public virtual void AddMapping(Action<TSource, TDest> mapping)
{
mappings.Add(mapping);
}
Again, simple yet functional.
Perform Mappings
The last thing we need is a couple of methods to execute the actual mapping:
public virtual TDest MapObject(TSource source, TDest dest)
{
CopyMatchingProperties(source, dest);
foreach(var action in mappings)
{
action(source, dest);
}
return dest;
}
public virtual TDest CreateMappedObject(TSource source)
{
TDest dest = new TDest();
return MapObject(source, dest);
}
You'll see that "CreatedMappedObject" was the reason we needed to have the new-able clause on the TDest generic parameter.
Usage
Now let's put this into action! Given a simple domain object and view model:
public class DomainObject
{
public string Name { get; set; }
public DateTime DOB { get; set; }
public int Age { get; set; }
public string Address { get; set; }
}
public class ViewModel
{
public string Name { get; set; }
public int Age { get; set; }
}
As you can see, our view model only needs the Name and Age. Our mapping code looks like this:
var mapper = new Mapper<DomainObject, ViewModel>();
var viewModel = mapper.CreateMappedObject(domainObject);
if the view model is created somewhere else and pre-populated with other data, we would use the MapObject method instead of creating a new instance of ViewModel:
var mapper = new Mapper<DomainObject, ViewModel>();
var viewModel = InitializeViewModel();
viewModel = mapper.MapObject(domainObject, viewModel);
Now let's assume we want to add the user's birth year to the view:
public class ViewModel
{
public string Name { get; set; }
public int Age { get; set; }
public int BirthYear { get; set; }
}
Yes, we could pass along the entire date of birth, but this way the view model is getting only what it needs and doesn't need to do any additional processing to get the year:
var mapper = new Mapper<DomainObject, ViewModel>();
mapper.AddMapping((source,dest) => dest.BirthYear = source.DOB.Year);
var viewModel = mapper.CreateMappedObject(domainObject);
To encourage re-use and centralize the setup of any custom transformations, I create a subclass of my Mapper class:
public class DomainModelToViewModelMapper : Mapper<DomainObject, ViewModel>
{
public DomainModelToViewModelMapper()
{
this.AddMapping((s, d) => d.BirthYear = s.DOB.Year);
}
}

|
How Does Simple Text Markup Differ Across The Office 2007 Suite
Tim Murphy
- Posted 2/4/2010 6:52 AM
|
Note: Cross posted from Coding The Document.
Permalink
Our theme recently is things that need to be made more consistent in the office products in order to make document generation development more efficient for developers. This time around we will focus on difference between the way text is marked up in Word and PowerPoint. I have found that there are a number of subtle but important differences in the way text is written to the Open XML standard. This is then reflected in the Open XML SDK’s API. Examples of these differences are apparent in features such as text color, bolding, underlining and bulleted lists. The main difference seems that the Word team seems to have taken a more object approach and conversely the PowerPoint team seems to favor attributes. The result is that the PowerPoint definition ends up with more moving parts. To illustrate this let’s take a look at the setting of text color and underlining a group of text. Text color is handled in Word simply by applying a Color object to the run properties. PowerPoint requires a SolidFill object and child SchemeColor and LuminanceModulation objects to get the same effect. The differences in the way that text is bolded is very similar. In Word the run is assigned a bold object, but PowerPoint it is a boolean attribute of the run properties. So what is the impact to the developer. Code reuse for those of us who have to generate both documents and presentations is next to nothing. On top of that the learning curve is practically doubled. I realize that the two products have evolved through separate paths and isolated team, but time for that type of development is long past. The Open XML standard should be unified where ever possible across the Office Applications and allow for greater interaction between the products. Ultimately the synchronizing of these tools will lead to greater adoption. 
|
Custom Action eines Setup-Projektes wird nicht ausgeführt
thomas woelfer
- Posted 2/4/2010 5:43 AM
|
|
Das hat mich nun etwa 2 Tage gekostet - vielleicht hilft es ja mal jemand anderem...
Ich hatte folgendes Problem: In meinem VS (2008) Setup-Projekt gab es eine Custom
Action (als C# Projekt) Assembly - und die wurd beim testen des Setups auf einer Maschine
einfach nicht ausgeführt. (Das Ding schreibt einen Event-Log Eintrag, mit dem das
einfach nachzuvollziehen war.)
Grund: Der MSI scheint bei Custom Actions Assemblies ein etwas anderes Verhalten an
den Tag zu legen, als bei "normalen" Assemblies. Im Normalfall reicht es bei einer
Managed Assembly aus, das die neue Version der Assembly eine höhere AssemblyVersion
(per AssemblyVersionAttribute [1.0.0.*] einfach zu handhaben) hat, als eine auf dem
Zielsystem bereits vorliegende Assembly. Hat die "neue" eine höhere Version, wird
die "ältere" ersetzt. (Bei nativen Images muss die FileVersion höher sein, damit die
ersetzt werden.)
Bei einer Assembly die eine Custom Action enthält scheint es nicht auszureichen die
AssemblyVersion Notation [1.0.0.*] zu verwenden - auch wenn die Version hochgezählt
wird, ersetzt MSI eine bereits vorliegende DLL mit gleichem Namen nicht. Offenbar
muss man bei Custom Actions auf jeden Fall auch eine höhere FileVersion (per AssemblyFileVersionAttribute
zu vergeben) haben. Ist das der Fall, wird die "ältere" DLL dann auch durch die neuere
ersetzt - und im Zuge der Ausführung der Custom Actions dann auch tatsächlich aufgerufen.
Wäre schön gewesen, wenn das irgendwo in der Dokumentation zu finden gewesen wäre.
:-(
This weblog is sponsored by D.I.E. CAD und Statik Software
GmbH.
|
ASP.NET PowerShell Data Source Control
Adam Weigert
- Posted 2/3/2010 10:26 PM
|
|
Extending on the small proof-of-concept I mentioned yesterday I created this simple data source control that lets you bind a Repeater or DataGrid to it like an ObjectDataSource control but it executes a PowerShell script to retrieve the results. <asp:PowerShellDataSource ID="EmployeesDataSource" runat="server"> [PSObject]"" | Add-Member NoteProperty "Title" "Software Engineer" -passThru | Add-Member NoteProperty "Name" "Mike Wolford" -passThru [PSObject]"" | Add-Member NoteProperty "Title" "Software Evangelist" -passThru | Add-Member NoteProperty "Name" "Scott Root" -passThru </asp:PowerShellDataSource>
<asp:Repeater runat="server" DataSourceID="EmployeesDataSource"> <ItemTemplate> <h4><%# DataBinder.Eval(Container.DataItem, "Title") %>: <%# DataBinder.Eval(Container.DataItem, "Name") %></h4> </ItemTemplate> </asp:Repeater>
If this is something that interests you, take a look over at http://aspower.codeplex.com/
|
Parallelism in .NET – Part 8, PLINQ’s ForAll Method
Reed Copsey, Jr.
- Posted 2/3/2010 7:21 PM
|
|
Parallel LINQ extends LINQ to Objects, and is typically very similar. However, as I previously discussed, there are some differences. Although the standard way to handle simple Data Parellelism is via Parallel.ForEach, it’s possible to do the same thing via PLINQ.
PLINQ adds a new method unavailable in standard LINQ which provides new functionality…
LINQ [...]
|
Introduction to Security in .NET
Senthil Kumar B
- Posted 2/3/2010 9:35 AM
|
|
When working with Security , it is important to understand these 2 terms .
Authentication is the process of determining whether the user can access the system . Commonly used ways of authentication user name and a password.
Authorization : Once the user is authenticated , this process identifies the level of access allowed to a given [...]
|
Some VS2010 news
Sven Cipido
- Posted 2/3/2010 1:21 AM
|
|
Some announcements about VS2010:
-
MS Visual Studio Test Elements 2010 will be renamed to MS Visual Studio Test Professional
2010
-
MS Test and Lab Manager will be renamed to MS Test Manager 2010
-
MS Visual Studio Team Lab Management 2010 will be renamed to MS Visual Studio
Lab Management 2010
-
Pricing details for VS2010 are release
All this info and a bit more background info can be found here http://blogs.msdn.com/slange/archive/2010/01/26/it-s-official-vs-2010-branding-pricing.aspx.
My thoughts, shares,... with .Net and Microsoft - The blog of Sven Cipido
|
VB.NET Conversions
Rob Chartier
- Posted 2/3/2010 1:10 AM
|
|
There was some discussion around the office which touched on the topic for the best method for object conversion in VB.NET. Given this (typical) pattern: 1: Dim sneakers As Cat = CType(Factory.GetObject(someKey), Cat)
2:
3: If (sneakers Is Nothing) Then
4: ...
5: End If
I personally have always felt that CType was not the preferred method, so I decided to do some digging.
Lets start with the basic performance test, the sample code…
1: Dim max As Integer = 1000000
2: Dim sw As New System.Diagnostics.Stopwatch
3: Dim duration As TimeSpan
4: sw.Start()
5: For index As Integer = 1 To max
6: Dim MyObject As Object = "Hello World"
7: Dim MyString1 As String = CType(MyObject, String)
8: Next
9: duration = New TimeSpan(sw.ElapsedTicks)
10: Console.WriteLine("CType Value Type to Object:{0:0.00000}", duration.TotalMilliseconds)
11: sw.Reset()
12:
13: sw.Start()
14: For index As Integer = 1 To max
15: Dim MyObject As Object = "Hello World"
16: Dim MyString1 As String = DirectCast(MyObject, String)
17: Next
18: duration = New TimeSpan(sw.ElapsedTicks)
19: Console.WriteLine("DirectCast Value Type to Object:{0:0.00000}", duration.TotalMilliseconds)
20: sw.Reset()
21:
22: sw.Start()
23: For index As Integer = 1 To max
24: Dim MyObject As Object = "Hello World"
25: Dim MyString1 As String = TryCast(MyObject, String)
26: Next
27: duration = New TimeSpan(sw.ElapsedTicks)
28: Console.WriteLine("TryCast Value Type to Object:{0:0.00000}", duration.TotalMilliseconds)
29: sw.Reset()
30:
31:
32: sw.Start()
33: For index As Integer = 1 To max
34: Dim MyObject As New Cat
35: Dim MyString1 As Cat = CType(MyObject, Cat)
36: Next
37: duration = New TimeSpan(sw.ElapsedTicks)
38: Console.WriteLine("CType Ref type to Object:{0:0.00000}", duration.TotalMilliseconds)
39: sw.Reset()
40:
41: sw.Start()
42: For index As Integer = 1 To max
43: Dim MyObject As New Cat
44: Dim MyString1 As Cat = DirectCast(MyObject, Cat)
45: Next
46: duration = New TimeSpan(sw.ElapsedTicks)
47: Console.WriteLine("DirectCast Ref type to Object:{0:0.00000}", duration.TotalMilliseconds)
48: sw.Reset()
49:
50: sw.Start()
51: For index As Integer = 1 To max
52: Dim MyObject As New Cat
53: Dim MyString1 As Cat = TryCast(MyObject, Cat)
54: Next
55: duration = New TimeSpan(sw.ElapsedTicks)
56: Console.WriteLine("TryCast Ref type to Object:{0:0.00000}", duration.TotalMilliseconds)
And the output it yields:
CType Value Type to Object:3.95910
DirectCast Value Type to Object:1.17570
TryCast Value Type to Object:1.07470
CType Ref type to Object:7.62320
DirectCast Ref type to Object:6.41400
TryCast Ref type to Object:6.58750
Notice that CType consistently performs worse than both DirectCast and TryCast in both usage scenarios (By Value and by Reference).
Ok, so now we all know to avoid CType and prefer either DirectCast or TryCast. The next logical question is…
What is the difference between DirectCast and TryCast and which one should we use for this situation.
The answer will come from the documentation for VB.NET. At the time of writing this, the URL for the answer can be found here: http://msdn.microsoft.com/en-us/library/zyy863x8%28VS.80%29.aspx
Here is a snippet of the page, I bolded the significant portions:
If an attempted conversion fails, CType and DirectCast both throw an InvalidCastException error. This can adversely affect the performance of your application. TryCast returns Nothing (Visual Basic), so that instead of having to handle a possible exception, you need only test the returned result against Nothing.
You use the TryCast keyword the same way you use the CType Function and the DirectCast keyword. You supply an expression as the first argument and a type to convert it to as the second argument. TryCast operates only on reference types, such as classes and interfaces. It requires an inheritance or implementation relationship between the two types. This means that one type must inherit from or implement the other.
| Method |
Types |
Throws |
| CType |
Any |
InvalidCastException |
| DirectCast |
Any |
InvalidCastException |
| TryCast |
Reference Only |
None |
So, since our specific scenario deals with reference types, our preferred method would be to use TryCast. In any other case we will be forced to use DirectCast and remember to watch out for that costly InvalidCastException.
Side Note: If you noticed that we are actually using a String (value type) with TryCast and we are not seeing any compile time error, this is due to the fact that since the ToString() method is defined for all objects, you will always be able to cast to a string.
|
Using SpecFlow + WatiN or BDD for web applications without leaving the CLR.
Hernan Garcia
- Posted 2/2/2010 11:01 PM
|
|
Last week I wrote about using cucumber to test your web applications outside in. In
the post I showed a simple example (actually comes with cucumber) to open a browser,
go to a site and perform some actions.
I showed the same to my team at work and they mention that could be nice to been able
to use c# and Visual Studio to do something similar.
After thinking about it I decided to give another try to a tool I check a few month
ago. SpecFlow.
SpecFlow is a tool and a set of libraries to write specifications using Gherkin.
You can check the screencast
here or read this
post from Ryan Lanciaux. SpecFlow can use either NUnit or MsTest as the engine.
Now I needed something to drive the browser. WatiN is
the .Net port of WatiR and is very
easy to use. The problem is that needs to run in a single thread process, so when
called from inside an NUnit test we need to add the STAThreadAttribute to the Test
method.
Of course, this is not a problem when you are writing the Test methods yourself but
the way SpecFlow works is that the actual Test method is generated by a tool from
your .feature file.
The code looks like this (actually I edited it a little bit to make it nicer).
So you need to add the STAThreadAttribute to
this method.
This works great and I was able to drive the browser and write a few test in no time.
The problem is that if you edit every time you edit the .feature
file this class will be re-generated and you will have to re-add this attribute. (Note: I
forked the repo on GitHub, made a change to the source code and sent a pull request
to add this attribute by default, not sure if it will be accepted or not).
I think that the integration from SpecFlow with VS is great. If you or your team feel
very strong on using VS this is a very good tool (there are versions for both VS 2008
and 2010). After writing the features and running the test you will have hints and
code to copy and paste from the TestRunner into the specification class.
You will generate the specification from an item template.
Conclusion:
I think that this is a great tool, specially if you are using it to develop desktop
apps or library code in c#. You can use tools like R# to generate your classes and
methods from the step definition class directly.
For using with WatiN or similar tools to drive the browser I will probably keep using
pure cucumber with Ruby at least until the STAThread issue
gets solved.


|
Chapter 2 from Microsoft Visual C# 2008:Data Types aka Types
Steve Schofield
- Posted 2/2/2010 7:10 PM
|
|
Been a couple weeks regarding my adventure in C# class. This was my first formal venture into data types, Intrinsic, Integral and other categories. I learned decimal was more precise than Double. All programming I've done basically uses Long, Double, Integer, String, and Boolean. Also, when declaring float, decimal as a variable, I need to add a 'thing' at the end.
float MyVariable = 4.87F; Is one example. That seems a tad quirky! I know I know, my background is VB/VBScript/VB.NET. No language is perfect, just kidding to the purists. :) Here is a link to the data types.
http://msdn.microsoft.com/en-us/library/s1ax56ch(VS.80).aspx
And yes I'm doing math again. The class has many story problems which many are story problems. Do you guys remember doing story problems in Math class. Not sure I did very well. Remember this rule? P.E.M.D.A.S (http://answers.yahoo.com/question/index?qid=20070719023408AAL0Jkb) I also hadn't messed with Compare(), CompareTo() methods and StartsWith(). These are handy functions. We covered CONSTANTS, and taking input on Console Applications READLINE(). It was a pretty short and straight forward chapter. I picked up a few things. Anywho! Happy C# programming.
|
Personal | Going to Haiti on Thursday
Jeff Julian
- Posted 2/2/2010 12:59 PM
|
|
On Thursday, February 4th, I am leaving with 7 other men from my church to go to Port-au-Prince, Haiti to work in a temporary orphanage for a week. I am definitely excited to go on this trip and I really feel God is calling me to go and spread the gospel and bring whatever joy I can to these children. We are going with a ministry called the Global Orphan Project based in Kansas City. They currently have several orphanages around the world and in Haiti, but with the need for more homes for orphans after the earthquake, they created a Temporary Village outside of Port-au-Prince and this is where we will be working. We are hoping to return next Monday, but we may stay until Tuesday. The main goal for our team is to interact with the children at the village by playing games, telling stories, drawing, and just being a kid. After nearly 18 months in youth ministry, I know how to think quick when it comes to making up games, so I should have some skills in this area. Tonight we are packing our bags as a group. We are allowed two 50lbs bags on the flight along with our carry-on so we are packing the two bags with clothing, games, dental products, soccer balls, crayons, and other supplies for the children and our stuff in the carry-ons. I would like to solicit as much prayer as I can for our team while we are on this trip. I know we are about to enter a country that has been devastated by this earthquake and some of the experiences I have will be life changing. (Side Note: Yes, I know, do not take the children outside of the country would out the appropriate paperwork.) 
|
Tracing changes in MySQL Connector/Net 6.2 – Part 2
Reggie Burnett
- Posted 2/1/2010 3:57 PM
|
|
In our last installment we found our hero investigating the tracing changes found in Connector/Net 6.2. This time we’ll take a closer look at the format of the trace data and how developers can use that information to write new and interesting trace listeners.
Understanding the plumbing
The first thing we need to understand is a little More >
|
[Silverlight 3/4] Comment faire des contrôles avec deux faces différentes ?
Courtois Sébastien
- Posted 2/1/2010 1:38 PM
|
Au commencement Microsoft créa Silverlight. Silverlight, la technologie RIA nouvelle génération pour créer des applications vectorielles entièrement en code managé. Microsoft vit que Silverlight était bon… mais qu’il lui manquait un petit truc pour rivaliser avec son rival. Alors Microsoft dit : “Que la 3D soit” et la 3D fut intégrée dans Silverlight … enfin [...]
|
|