Wednesday, April 14, 2010
Visual Studio 2010 / .NET 4.0 and WinForms
As expected, there is nothing new in WinForms except the fact that it can make use of many new .NET 4.0 features like MEF. And of course, there will be bug fixes and performance improvements as the Group Manager of WinForms says in response to a comment in Somasegar's Blog: "We continue to invest in WinForms for .NET FX 4. This includes the core expectation of maintaining compatibility for applications already written in WinForms, fixing bugs that developers have reported, contributing to overall developer experiences across Visual Studio, as well as perf work and some feature development."
That "some feature" he mentioned is not to be seen any where. Look at the What's New in the .NET Framework 4 article in MSDN. It doesn't even mention WinForms!
Those who are still fond of WinForms find it comforting to say that "WPF is still growing and it need much attention unlike WinForms which is matured and used for many critical LOB applications around the world." :)
Friday, October 30, 2009
MEF in .NET 4.0/Visual Studio 2010 – Simple Example
Let us examine the basics of MEF through a very plain example application. I am building a WinForms showroom application which will display different vehicles. I have my own vehicles to display, and the application also supports vehicles from other vendors (aka plugins). All they need to do is to stick to my contract (aka implement the interface I give) while they develop their vehicles.
Let us first define the required contract. In Visual Studio 2010 (My version is Beta 2), create a new C# class library project and name it as Showroom.Contracts. Add an interface to it as below:
namespace Showroom.Contracts { public interface IVehicle { string GetVehicleDetails(); } }
Now let us assume that we distribute this contract (interface library) to other vendors so that they can create vehicles that will fit in our showroom. To portray this scenario add another class library project named Vehicle.Hyundai. Add Showroom.Contracts project as a reference to this project as we need to implement the contract interface. This is going to be a plugin (extension or ComposablePart in MEF terminology) and hence we need to also add a reference to the MEF library System.ComponentModel.Composition. Add a class as shown below to this project:
namespace Vehicle.Hyundai { using System.ComponentModel.Composition; using Showroom.Contracts; [Export(typeof(IVehicle))] public class HyundaiSonata : IVehicle { string IVehicle.GetVehicleDetails() { return "Hyundai Sonata"; } } }
Notice the Export attribute. This informs MEF that this is a plugin of type IVehicle. Now let us add one more similar class:
namespace Vehicle.Hyundai { using System.ComponentModel.Composition; using Showroom.Contracts; [Export(typeof(IVehicle))] public class HyundaiSantro : IVehicle { string IVehicle.GetVehicleDetails() { return "Hyundai Santro!"; } } }
To portray one more vendor, add another class library project named Vehicle.Maruti and add a similar class to this as well:
namespace Vehicle.Maruti { using System.ComponentModel.Composition; using Showroom.Contracts; [Export(typeof(IVehicle))] public class MarutiSwift : IVehicle { string IVehicle.GetVehicleDetails() { return "Maruti Swift"; } } }
Now that the contract and plugins based on these contracts are ready, let us build the showroom host or shell application to display these vehicles. Add a new WinForms project to the solution named Showroom.Shell. Add a project reference to Showroom.Contracts and reference to System.ComponentModel.Composition. Add a listbox to the form and name it as uxVehicles. This will display all the vehicles we have.
Remember we have our own vehicles to display in the showroom (besides vehicles from other vendors). Let us add a new class to the project:
namespace Showroom.Shell { using System.ComponentModel.Composition; using Showroom.Contracts; [Export(typeof(IVehicle))] public class ShowroomVehicle1: IVehicle { string IVehicle.GetVehicleDetails() { return "Showroom Vehicle Normal"; } } }
And one more similar one:
namespace Showroom.Shell { using System.ComponentModel.Composition; using Showroom.Contracts; [Export(typeof(IVehicle))] public class ShowroomVehicle2 : IVehicle { string IVehicle.GetVehicleDetails() { return "Showroom Vehicle Special"; } } }
Note that these are also decorated with Export attribute for MEF to pick them up later. Now go to the source code of Form1 to build the shell logic:
namespace Showroom.Shell { using System; using System.Collections.Generic; using System.ComponentModel.Composition; using System.ComponentModel.Composition.Hosting; using System.Reflection; using System.Windows.Forms; using Showroom.Contracts; public partial class Form1 : Form { [ImportMany(typeof(IVehicle))] public List<IVehicle> Vehicles { get; set; } public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { this.Vehicles = new List<IVehicle>(); AggregateCatalog cat = new AggregateCatalog(); cat.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly())); cat.Catalogs.Add(new DirectoryCatalog("Plugins")); CompositionContainer contnr = new CompositionContainer(cat); contnr.ComposeParts(this); foreach (IVehicle item in this.Vehicles) { uxVehicles.Items.Add(item.GetVehicleDetails()); } } } }
We have declared a property named Vehicles to contain all the vehicles we plan to display in our showroom. Notice the ‘ImportMany’ attribute. It tells MEF that this property need to be loaded using plugins of type ‘IVehicle’. We have used ‘ImportMany’ as there are more than one vehicle and will be using ‘Import’ instead if there is only one plugin.
MEF's core is comprised of a catalog and a CompositionContainer. A catalog is responsible for discovering extensions (plugins) and the container coordinates creation and satisfies dependencies. The AssemblyCatalog gathers plugins from an assembly. Here we have asked it to find all the plugins (classes with ‘Export’ attributes) from the currently executing assembly (Showroom.Shell). The DirectoryCatalog gathers plugins from a directory. Here we have asked the catalog to look in a directory named ‘Plugins’ for the assemblies containing classes that have ‘Export’ attribute. We have used AggregateCatalog to aggregate the tow different (Assembly and Directory) catalogs of plugins into one. The ComposeParts method of the CompositionContainer does all the magic by importing the required types from these plugins and loading them to the corresponding properties. Here in our code, the property ‘Vehicles’ will now be loaded with all the available vehicle plugins and we call their ‘GetVehicleDetails’ methods to add the results to a the listbox.
Before running this application, copy the plugin assemblies (Vehicle.Hyundai.dll and Vehicle.Maruti.dll) to a folder named ‘Plugins’ under ..\bin\Debug\ folder of the Showroom.Shell project.
Download the complete sample (works in Visual Studio 2010 Beta 2) from here http://wayfarer.bizhat.com/techbites/downloads/mef_showroom1.zip
Thursday, October 29, 2009
Visual Studio 2010 and .NET 4.0 Features
Here are some of the new features (collected from various blogs including ScottGu's Blog and Kevin McNeish's Blog):
Visual Studio
- Fresh look and feel with a blue based new logo and color theme.
- Works side by side with VS 2008 and supports Multi Targeting (.NET 2.0, 3.0, ...).
- New Product Lineup (Express, Professional, Premium, Ultimate).
- Multi-Monitor Support (editors, designers and tool-windows).
- Silverlight UI layout support.
- Data binding support for both WPF and Silverlight.
- Zoom in/out of any code editing window or text editing window.
- Call hierarchy for C# is available at design time (Similar to stack trace; Right click on a symbol(method or class, etc.) and choose View Call Hierarchy).
- Naviagate To (Edit > Navigate To or Ctrl+Comma) option to do quick search for a symbol or file in the source code (can search part of a name or abbreviation like IC for InitializeComponent, and can specify multiple strings separated by space).
- Highlight References: Put the cursor on a symbol and after a short delay, all its references are highlighted. Or use Find all references (Right click on a symbol and choose Find All References) to see all its instances.(Ctrl-Shift-up/down arrow to cycle)
- Consume First Development: Even if there is no class by name Person, you can type Person obj = new Person(); and then choose to generate the class. (Ctrl+ Dot)
- Tools > Extension Manager to manage add-ins.
- Dynamic Language Support. [kind of late binding: dynamic Car = GetCar();]
- MEF (Managed Extensibility Framework) for developing applications that supports plugins.
- Optional Parameters [Supply a default value to make it optional: public void CreateBook(string title="No Title", string isbn = "0-00000-000-0"){}]
- Named Parameters [Supply parameter values in any order specifying its name: CreateBook(isbn: "5-55555-5555-5"); or CreateBook("Book Title", isbn: "5-55555-5555-5");]
- Co-variance and Contra-variance support [IEnumerable<string> strings = GetStrings();IEnumerable<object> objects = strings; is now possible.]
- Starter Project Templates (Installed & Online; Empty, Normal, MVC, Ajax, etc.).
- Clean Web.Config Files.
- Code Optimized Web Development Profile(Or Tools>Options>HTML Designer>Off Designer)
- ASP.NET, HTML, JavaScript Snippet Support.
- Auto start: Only on IIS 7.5 (well-defined approach to perform expensive application startup).
- URL Routing with ASP.NET 4 Web Forms.
- New controls: DataGrid, DatePicker, and Calendar
- Bag O’ Tricks controls: AnimatingTilePanel, ColorPicker, InfoTextBox, ListPager, NumericUpDown, Reveal, TransitionsPresenter, TreeMapPanel.
- Extra control: Windows 7 & Office Ribbon Control
- Graphics improvements: Cached Composition, Pixel Shader 3 Support, LayoutRounding, Animation Easing Function, CleartypeHint
- Text improvements: New Text Rendering Stack, Display-optimized character layout, explicitly selecting aliased, grayscale, or ClearType rendering modes, optimizing text hinting and snapping, support for fonts with embedded bitmaps, BindableRun (Run.Text), Custom Dictionaries, Selection and Caret Brush
- Windows 7 Multitouch Support: Multi-touch Manipulation, Inertia (Pan, Zoom, Rotate) events on UIElement, Raw multi-touch events (Up, Move, Down) on UIElement, UIElement3D and ContentElement, Multiple capture supporting multiple active controls, ScrollViewer enhancement to support multi-touch panning, Touch device extensibility, Future Surface SDK compatibility
- Windows 7 Shell Integration: Jump List (Tasks, Items, Recent and Frequent Lists) and Taskbar (Progress bar, Overlay Icon, Thumbnail buttons with commanding support, Description Text) integration
- Fundamentals: New XAML/BAML Parser Engine, Data Binding Support for DLR, Visual State Manager (VSM), HTML-XBAP Script Interop, UIAutomation Virtualization, SynchronizedInput Pattern
- Deployment: .NET Framework 4 Client Profile, Full Trust XBAP Deployment
- No new features or controls!
- Will maintain compatibility for applications already written in WinForms.
- Bug fixes and perf improvements.
Wednesday, February 27, 2008
VS 2008 and Visio AddIn Deployment Issues
While installing this application on a client machine using ClickOnce, it never ask you for an installation path and it copies the files into two different folders with random names! Mine looked like this:
C:\Users\Administrator\AppData\Local\Apps\2.0\CA5NQ9ZB.N44\E6TLT686.69V\visi..vsto_11aeaa34550a68ee_0001.0000_14f3717c0aa57ea0
C:\Users\Administrator\AppData\Local\Apps\2.0\CA5NQ9ZB.N44\E6TLT686.69V\visi...dll_11aeaa34550a68ee_0001.0000_none_47ef10bd354219e1
And the frustrating thing is that all dlls gets copied to the first folder and the data files to the other. So my application never found the file it needed to load and I had no idea on how to solve this as the folder names kept changing randomly with every new deployment. I think these are some caching locations and the application dlls were not available anywhere else. Do anybody know what is happening here and what is the solution?
Finally I made my Deployment work by making the data file as an embedded resource (Properties > Build Action) and reading the data as below:
Stream resourceStream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(MyNamespace.MyClass.MyFile.xml");
TextReader tr = new StreamReader(resourceStream);
Monday, December 05, 2005
Linguistic Nimbility
DSV-Data Source View
RDL-Report Definition Language
SMDL-Semantic Model Definition Language
SMQL-Semantic Model Query Language
TFC-Team Foundation Client
TFCS-Team Foundation Core Services (Earlier Burton Integration Services)
TFS-Team Foundation Server
VSTF-Visual Studio Team Foundation
VSTS-Visual Studio Team System
WITDL-Work Item Type Definition Language
WIQL-Work Item Query Language
Code Names
Everything in software has to have a code name. Why is that, you might ask? The reason is that no-one is allowed to name a software product or component except for marketing. And marketing is not willing (and rightfully so) to name a software product until the very last minute before it comes out. So, software teams come up with code names to refer to the product or feature they are working on.
Burton-Visual Studio Team System
Cassini-VS 2005 Built-in Web Server
Currituck-VSTS Work Item Tracking System
F1-VSTS Profiling System.
FxCop-Static Code Analyzers for managed code
Hatteras-VSTS Source Control System
Longhorn-Windows Vista
Okracoke-VSTS Web Testing System
Orcas-Visual Studio 200x targeting Longhorn
PREfast-Static Code Analyzers for C/C++ code
Rosetta-SQL Server 2005 Reporting Services
Whidbey-Visual Studio 2005 and .NET Framework 2.0
Whitehorse-VSTS Distributed System Designers
Yukon-SQL Server 2005
DLL Names (Beta and Final)
Microsoft.VisualStudio.Currituck.Client-Microsoft.TeamFoundation.WorkItemTracking.Client
Microsoft.VisualStudio.Currituck.Cache-Microsoft.TeamFoundation.WorkItemTracking.Client.Cache
Microsoft.VisualStudio.Currituck.Controls-Microsoft.TeamFoundation.WorkItemTracking.Controls
Microsoft.VisualStudio.Hatteras.Client -Microsoft.TeamFoundation.VersionControl.Client
Microsoft.VisualStudio.Hatteras.Diff-Microsoft.TeamFoundation.VersionControl.Common.DiffEngine
Microsoft.visualstudio.teamsystem.elead.common-Microsoft.TeamFoundation.Common.Library
Microsoft.visualstudio.teamsystem.elead.sdk-Microsoft.TeamFoundation
Microsoft.visualstudio.teamsystem.elead.vsip.sdk-Microsoft.VisualStudio.TeamFoundation.Client
Microsoft.visualstudio.textmanager.interop-Microsoft.VisualStudio.TextManager.Interop