Code coverage is used to determine how effectively your tests exercise the code in your application. This way you can identify sections of code that are covered, not covered or partially covered by your tests. Visual Studio uses 2 different types of analysis, block-based statement coverage (C1 coverage) and line-based coverage. - Block-based statement coverage
A block is defined as a sequence of instructions that have a single entry point and a single exit point. Exit points include branch instructions, a function call, a return instruction, or, for managed code, a throw instruction. - Line-based coverage
For line-based coverage, the tools identify all of the blocks that make up a line and then use this information to determine the level of coverage for the line. If all of the blocks that make up the line are covered, then the tools report that the line is covered. If no blocks in the line are covered, then the tools report that the line is not covered. If some, but not all, of the blocks in the line are covered, then the tools report that the line is partially covered. Take for example the following class that reside in MyProject.BusinessLogic assembly public class Foo
{
public int Calculate(int x, int y)
{
if (x > 0 && y < 0)
{
return -1;
}
else
{
return 1;
}
}
And a unit test that reside in MyProject.BusinessLogic.Test assembly
[TestClass]
public class FooTest
{
[TestMethod]
public void Calculate()
{
Foo foo = new Foo();
Assert.AreEqual(1, foo.Calculate(3, 4));
}
}
To enable code coverage you need to double-lick on the LocalTestRun.testrunconfig file that is located in the 'Solution Items' folder.
Inside the 'Code Coverage' tab you select the assembly that you want to instrument. In this case we select MyProject.BusinessLogic.dll assembly.
Now you will need to run your unit tests again. Note that code coverage doesn't work when you debug your unit tests, so you will need to run your unit tests through the menu 'Test –> Run –> All Tests in Solution (CTRL+R, A)'. After that you can view a report about the code coverage results through the menu 'Test –> Windows –> Code Coverage Results'.
From the results we notice that we don't have 100% code coverage because our unit test only reached one part of the condition inside the Calculate method. If you open the Foo class and enable the code coloring you see the parts that are covered, not covered or partially covered.
- Light Blue: Indicates that the entire line of code was exercised in the test run.
- Beige: Indicates that only a portion of the code blocks within the line of code were exercised in the test run.
- Reddish Brown: Indicates that the line was not exercised in the test run.
Code coverage inside Visual Studio uses statement coverage and in this case the number of IL instructions reached is taken into account. If we add some statements in the Foo class and run again our code coverage we notice that the coverage has been raised form 71,43% to 92,59%. It's important to notice, that when you refactor your class it influences the code coverage even when the contract of the class is the same! This is very different from Branch coverage where each control structure is evaluated to true and false. In this case we would have 50% code coverage. public class Foo
{
public int Calculate(int x, int y)
{
if (x > 0 && y < 0)
{
return -1;
}
else
{
Console.WriteLine(x.ToString());
Console.WriteLine(x.ToString());
Console.WriteLine(x.ToString());
Console.WriteLine(x.ToString());
Console.WriteLine(x.ToString());
Console.WriteLine(x.ToString());
Console.WriteLine(x.ToString());
Console.WriteLine(x.ToString());
Console.WriteLine(x.ToString());
Console.WriteLine(x.ToString());
return 1;
}
}
}
Often you have the need to iterate through a collection and most of the time the iteration logic is weaved with the action that need to be done. This is because we are used to program in an imperative approach. In some scenarios it's better to use a functional approach and let other functions decide which action need to be applied. This way we can for example reuse our iteration logic. Below is an iterator that starts from a solution or project and iterates through all project items inside the solution. public class ProjectItemIterator : IEnumerable<EnvDTE.ProjectItem>
{
IEnumerable<EnvDTE.Project> projects;
public ProjectItemIterator(EnvDTE.Solution solution)
{
if (solution == null)
throw new ArgumentNullException("solution");
projects = solution.Projects.Cast<EnvDTE.Project>();
}
public ProjectItemIterator(IEnumerable<EnvDTE.Project> projects)
{
if (projects == null)
throw new ArgumentNullException("projects");
this.projects = projects;
}
public IEnumerator<EnvDTE.ProjectItem> GetEnumerator()
{
foreach (EnvDTE.Project currentProject in projects)
foreach (var currentProjectItem in Enumerate(currentProject.ProjectItems))
yield return currentProjectItem;
}
IEnumerable<EnvDTE.ProjectItem> Enumerate(EnvDTE.ProjectItems projectItems)
{
foreach (EnvDTE.ProjectItem item in projectItems)
{
yield return item;
if (item.SubProject != null)
{
foreach (EnvDTE.ProjectItem childItem in Enumerate(item.SubProject.ProjectItems))
yield return childItem;
}
else
{
foreach (EnvDTE.ProjectItem childItem in Enumerate(item.ProjectItems))
yield return childItem;
}
}
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
Microsoft .NET RIA Services simplifies the traditional n-tier application pattern by bringing together the ASP.NET and Silverlight platforms. RIA Services provides a pattern to write application logic that runs on the mid-tier and controls access to data for queries, changes and custom operations. It also provides end-to-end support for common tasks such as data validation, authentication and roles by integrating with Silverlight components on the client and ASP.NET on the mid-tier. To get started with .NET RIA Services you need Visual Studio 2008 SP1 and you need to install the following packages On the download page of .NET RIA Services there is a great PDF document (riaservicesoverviewpreview.pdf) that gives you a step-by-step guide. Every time you compile a solution with .NET RIA Services, an MSBuild task is executed that generates code in your Silverlight project from the domain services (DomainService class) that reside in your ASP.NET server. After some investigation through reflector, you can actually modify or extend the code generation using CodeDom! For this you need to add an attribute called DomainIdentifier where you specify a type that inherits from CodeProcessor. Both classes reside in the System.Web.Ria.Data namespace. [EnableClientAccess()]
[DomainIdentifier("Comment", CodeProcessor = typeof(CommentCodeProcessor))]
public class CityService : DomainService
{
//...
}
In this example, we simply add some documentation in the summary tag.
public class CommentCodeProcessor : CodeProcessor
{
public CommentCodeProcessor(CodeDomProvider codeDomProvider)
: base(codeDomProvider)
{
}
public override void ProcessGeneratedCode(
DomainServiceDescription domainServiceDescription,
System.CodeDom.CodeCompileUnit codeCompileUnit,
IDictionary<Type, System.CodeDom.CodeTypeDeclaration> typeMapping)
{
Type domainServiceType = domainServiceDescription.DomainServiceType;
CodeTypeDeclaration declaration = typeMapping[domainServiceType];
declaration.Comments.Add(new CodeCommentStatement("<summary>", true));
foreach (var entityType in domainServiceDescription.EntityTypes)
{
declaration.Comments.Add(
new CodeCommentStatement(
string.Format("Entity Type: {0}", entityType.FullName), true));
}
foreach (var operationEntry in domainServiceDescription.DomainOperationEntries)
{
declaration.Comments.Add(
new CodeCommentStatement(
string.Format("Operation Entry: {0}", operationEntry.MethodInfo.Name), true));
}
declaration.Comments.Add(new CodeCommentStatement("</summary>", true));
}
}
Below you find a sample of the generated file using the CommentCodeProcessor
/// <summary>
/// Entity Type: SilverlightApplication.Web.DataModels.City
/// Operation Entry: GetCities
/// Operation Entry: ReturnAllCities
/// </summary>
[DomainIdentifier("Comment")]
public sealed partial class CityContext : DomainContext
{
//...
}
In many applications you want to intercept WCF messages for doing stuff like, logging, tracing, passing a user context, language identifier, etc. Typically this can be done through the IClientMessageInspector that resides in the System.ServiceModel.Dispatcher. Unfortunately this interface doesn’t exist in Silverlight 2.0. Thankfully WCF is very extensible, and there is a sample Silverlight Web Services Samples on MSDN Code Gallery that shows how you can still use the IClientMessageInspector by implementing a custom binding. You simple use the BasicHttpMessageInspectorBinding that receives in the constructor an instance of type IClientMessageInspector. For example: BasicHttpMessageInspectorBinding binding = new BasicHttpMessageInspectorBinding(new TraceInspector());
Note that the sample only allows you to pass one inspector, if you need to pass several inspectors you can use the decorator pattern to pass multiple. public class ClientMessageInspectorDecorator : IClientMessageInspector
{
IClientMessageInspector[] inspectors;
public ClientMessageInspectorDecorator(params IClientMessageInspector[] inspectors)
{
this.inspectors = inspectors;
}
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
foreach (var item in inspectors)
{
item.BeforeSendRequest(ref request, channel);
}
return null;
}
public void AfterReceiveReply(ref Message reply, object correlationState)
{
foreach (var item in inspectors)
{
item.AfterReceiveReply(ref reply, correlationState);
}
}
}
In Part 1, we used the Unity block to intercept properties for dirty tracking. Our target class needed to implement the IDirty interface, and the setter properties (annotated with the Dirty attribute) assigned the Dirty flag (of IDirty) when the value has changed. Take for example the following classes: [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class DirtyAttribute : System.Attribute
{
}
public interface IDirty
{
bool IsDirty { get; set; }
}
public class Customer
{
public virtual string FirstName { get; [Dirty] set; }
public virtual string LastName { get; [Dirty] set; }
}
Note that in contrast to Part 1, the Customer object doesn’t implement the IDirty interface. In this example we are going to use a mixin for dirty tracking, a mixin is a class that provides a certain functionality to be inherited by a subclass, but is not meant to stand alone. That’s exactly what we want to achieve, that is to provide extra functionality, namely dirty tracking, to our Customer object.
We simply have to implement the IDirty interface once and for all and call it for example DirtyMixin.
[Serializable]
public class DirtyMixin : IDirty
{
public bool IsDirty { get; set; }
}
As interception and mixin mechanism we use Castle’s DynamicProxy, the latest build can be found here. To intercept our (dirty) properties we need to implement an interface called IInterceptor. In the implementation we write the code that need to be executed (advice) at particular points (pointcut) in the program. Note that with Unity we have the notion of IMatchingRule for defining Pointcuts, whereas in DynamicProxy we have to do it manually.
public class DirtyInterceptor : Castle.Core.Interceptor.IInterceptor
{
public void Intercept(Castle.Core.Interceptor.IInvocation invocation)
{
if (PointCut(invocation.Proxy, invocation.Method))
{
Advise(invocation.Proxy, invocation.Method, invocation.GetArgumentValue(0));
}
invocation.Proceed();
}
bool PointCut(object target, MethodInfo methodInfo)
{
if (IsSetter(methodInfo) && target is IDirty)
{
object[] dirtyAttributes = methodInfo.GetCustomAttributes(typeof(DirtyAttribute), true);
return (dirtyAttributes != null && dirtyAttributes.Length > 0);
}
else
{
return false;
}
}
void Advise(object target, MemberInfo methodInfo, object value)
{
string propertyName = methodInfo.Name.Substring("set_".Length);
PropertyInfo info = target.GetType().GetProperty(propertyName);
if (info != null)
{
object oldValue = info.GetValue(target, null);
if (!IsEqual(value, oldValue))
((IDirty)target).IsDirty = true;
}
}
bool IsSetter(MethodInfo methodInfo)
{
return (methodInfo.Name.StartsWith("set_")) && (methodInfo.GetParameters().Length == 1);
}
bool IsEqual(object valueX, object valueY)
{
if (valueX == null && valueY != null)
return false;
if (valueX != null && valueY == null)
return false;
if (valueX == null && valueY == null)
return true;
return valueX.Equals(valueY);
}
}
To generate our proxy we use the ProxyGenerator class that reside in the Castle.DynamicProxy2 assembly. Adding a mixin is done through the ProxyGenerationOptions which is passed to the CreateClassProxy method. var generator = new ProxyGenerator();
ProxyGenerationOptions options = new ProxyGenerationOptions();
options.AddMixinInstance(new DirtyMixin());
Customer customer = generator.CreateClassProxy(typeof(Customer), options, new DirtyInterceptor()) as Customer;
var firstname = customer.FirstName;
Debug.Assert(!((IDirty)customer).IsDirty);
customer.FirstName = "Piet";
Debug.Assert(((IDirty)customer).IsDirty);
The customer object that we receive from the generator is a proxy through subclassing and you will see that it now implements the IDirty interface.

You can use the PersistentProxyBuilder to save the generated assembly. It renders an assembly called CastleDynProxy2.dll. Below you find an example how you can use PersistentProxyBuilder. var generator = new ProxyGenerator(new PersistentProxyBuilder());
ProxyGenerationOptions options = new ProxyGenerationOptions();
options.AddMixinInstance(new DirtyMixin());
Customer customer = generator.CreateClassProxy(typeof(Customer), options, new DirtyInterceptor()) as Customer;
string proxyAssemblyPath = ((PersistentProxyBuilder)generator.ProxyBuilder).SaveAssembly();
var firstname = customer.FirstName;
Debug.Assert(!((IDirty)customer).IsDirty);
customer.FirstName = "Piet";
Debug.Assert(((IDirty)customer).IsDirty);
You can go a bit further and use an extension method that enables you to ask for a certain service. Internally it will simply try to cast to the given interface. public static class ObjectExtensions
{
public static T GetService<T>(this object instance) where T : class
{
return instance as T;
}
}
Given the GetService extension method, we use our customer as follow IDirty dirty = customer.GetService<IDirty>();
if (dirty != null)
{
var firstname = customer.FirstName;
Debug.Assert(!dirty.IsDirty);
customer.FirstName = "Piet";
Debug.Assert(dirty.IsDirty);
}
The source code of this article can be downloaded here (zipfile, 259.19 KB)
The last couple of days, I was converting my add-in visual studio called Component Dropper to WPF. One thing I noticed, is that the text in my WPF application was blurry, certainly when the font is small. It is harder to read and very unpleasant to work with. After some research, it appears to be a known problem. Check out the following threads, How to turn off anti aliasing for small text? and Blurry text in WPF – current status? and a very good explanation about the problem. It’s an issue that is already known for 2 years and there is still no solution for this particular problem. In my experience, enterprise applications are data-driven, which means there is a lot of text (= data) that need to be displayed typically in a grid (master-detail). WPF is really a great technology, but this is not a minor issue. I don’t think that your customers will be happy if they receive a new application that is hard to read.
In most enterprise applications, you end up by having a lot of cross-cutting concerns throughout your application. Most of the time, you have, for example, infrastructure code for doing logging, dirty tracking, lazy loading, caching, etc. Often infrastructure code is scattered over a number of modules making it harder to maintain and understand. Aspect-oriented programming (AOP) solves this problem by allowing the programmer to express cross-cutting concerns in stand-alone modules called aspects. When you apply domain-driven design, you often have the need for dirty tracking, check on a business entity whether the entity has changed (is dirty) or not. There are a lot of different implementations for dirty tracking, but in this article we are doing it by using an interface called IDirty that contains a property called IsDirty and the setter properties of your entity object calls the IsDirty if the value has changed. public interface IDirty
{
bool IsDirty { get; set; }
}
public class Customer : IDirty
{
private string _firstName;
private string _lastName;
public bool IsDirty { get; set; }
public string FirstName
{
get { return _firstName; }
set
{
if (value != _firstName)
IsDirty = true;
_firstName = value;
}
}
public string LastName
{
get { return _lastName; }
set
{
if (value != _lastName)
IsDirty = true;
_lastName = value;
}
}
}
As you can see from the example, if you have a lot of properties, you end up by having a lot of infrastructure code and repeated code in each setter. What we want to achieve, is to annotate the setter property through an attribute called DirtyAttribute and that the dirty logic is centralized in one module. [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class DirtyAttribute : System.Attribute
{
}
public interface IDirty
{
bool IsDirty { get; set; }
}
public class Customer : IDirty
{
public bool IsDirty { get; set; }
public virtual string FirstName { get; [Dirty] set; }
public virtual string LastName { get; [Dirty] set; }
}
Note that these are the only dependencies needed inside your domain model project. Now we need to make clear to Unity that we need to intercept the DirtyAttribute and execute some logic. With unity we denote a policy, a policy contains a set of matching rules and a set of call handlers. A matching rule will denote on which point the handler must be executed and the handler is the logic. In AOP this is called respectively a pointcut and an advice, the combination of the two is called an aspect. First, we are going to create our DirtyHandler by implementing the ICallHandler that resides in the Microsoft.Unity.Interception assembly. public class DirtyHandler : ICallHandler
{
public int Order { get; set; }
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
Advise(input.Target, input.MethodBase, input.Arguments[0]);
return getNext()(input, getNext);
}
private void Advise(object target, MemberInfo methodInfo, object value)
{
string propertyName = methodInfo.Name.Substring("set_".Length);
PropertyInfo info = target.GetType().GetProperty(propertyName);
if (info != null)
{
object oldValue = info.GetValue(target, null);
if (!IsEqual(value, oldValue))
((IDirty)target).IsDirty = true;
}
}
private bool IsEqual(object valueX, object valueY)
{
if (valueX == null && valueY != null)
return false;
if (valueX != null && valueY == null)
return false;
if (valueX == null && valueY == null)
return true;
return valueX.Equals(valueY);
}
}
Note that in the DirtyHandler we did not specify when the dirty logic is executed, this is done by a set of matching rules that implement the IMatchingRule interface. In our case we have three criterias, first that it can only be applied to a setter property, secondly that the setter property must be annotated with the DirtyAttribute and finally that the class must implement the IDirty interface. In Unity we have predefined rules that we can use, in our case we can use the PropertyMatchingRule and the CustomAttributeMatchingRule. To detect that a particular instance implements a given type, I created the InstanceOfMatchingRule. public class InstanceOfMatchingRule : IMatchingRule
{
private readonly Type _type;
public InstanceOfMatchingRule(Type type)
{
_type = type;
}
public bool Matches(System.Reflection.MethodBase member)
{
return _type.IsAssignableFrom(member.DeclaringType);
}
}
Now we are ready to configure our container for interception. Note that the interception mechanism inside Unity is implemented as an extension to the Unity block. Below we configure a policy named "DirtyPolicy" that executes the handler named "DirtyHandler" if it matches all three matching rules (PropertyMatchingRule, CustomAttributeMatchingRule and InstanceOfMatchingRule). In this example, we denote that the type Customer is configured with the VirtualMethodInterceptor. Note that this type of interception only works if your methods/properties are marked as virtual, which is the case for our Customer type (see Customer.cs). // Start Configuration
IUnityContainer container = new UnityContainer()
.AddNewExtension<Interception>()
.RegisterInstance<ICallHandler>("DirtyHandler", new DirtyHandler());
container.Configure<Interception>()
.SetInterceptorFor<Customer>(new VirtualMethodInterceptor())
.AddPolicy("DirtyPolicy")
.AddMatchingRule(new PropertyMatchingRule("*", PropertyMatchingOption.Set))
.AddMatchingRule(new CustomAttributeMatchingRule(typeof(DirtyAttribute), true))
.AddMatchingRule(new InstanceOfMatchingRule(typeof(IDirty)))
.AddCallHandler("DirtyHandler");
// End Configuration
var customer = container.Resolve<Customer>();
var firstname = customer.FirstName;
Debug.Assert(!customer.IsDirty);
customer.FirstName = "Piet";
Debug.Assert(customer.IsDirty);
The configuration part can also be done through a configuration file. Unfortunately, there is no schema available, this means that there is no validation and intellisense inside your Visual Studio! Especially to describe the matching rules through xml, I had to introduce some extra converters that implement the TypeConverter class. This enables you to convert to any kind of object started from a string. I introduced the PropertyMatchingOptionConverter and GetTypeConverter. public class PropertyMatchingOptionConverter : System.ComponentModel.TypeConverter
{
public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
return (PropertyMatchingOption)Enum.Parse(typeof(PropertyMatchingOption), value.ToString());
}
}
public class GetTypeConverter : System.ComponentModel.TypeConverter
{
public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
return Type.GetType(value.ToString());
}
}
Below you find how you use Unity with a configuration file and you find also the resulting xml file that does exactly the same as the above-mentioned version. IUnityContainer container = new UnityContainer();
UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
section.Containers["Default"].Configure(container);
var customer = container.Resolve<Customer>();
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="unity" type="....UnityConfigurationSection, ..."/>
</configSections>
<unity>
<typeAliases>
<typeAlias alias="bool" type="System.Boolean, mscorlib" />
<typeAlias alias="string" type="System.String, mscorlib" />
<typeAlias alias="int" type="System.Int32, mscorlib" />
<typeAlias alias="Type" type="System.Type, mscorlib" />
<typeAlias alias="GetTypeConverter" type="..."/>
<typeAlias alias="PropertyMatchingOptionConverter" type="..."/>
<typeAlias alias="InstanceOfMatchingRule" type="..."/>
<typeAlias alias="DirtyHandler" type="..."/>
<typeAlias alias="VirtualMethodInterceptor" type="..."/>
<typeAlias alias="CustomAttributeMatchingRule" type="..."/>
<typeAlias alias="PropertyMatchingRule" type="..."/>
<typeAlias alias="PropertyMatchingOption" type="..."/>
<typeAlias alias="DirtyAttribute" type="..."/>
<typeAlias alias="IDirty" type="..."/>
<typeAlias alias="Customer" type="..."/>
</typeAliases>
<containers>
<container name="Default">
<extensions>
<add type="....Interception, ..."/>
</extensions>
<extensionConfig>
<add name="interception"
type="....InterceptionConfigurationElement, ...">
<policies>
<policy name="DirtyPolicy">
<matchingRules>
<matchingRule name="SetPropertyRule" type="PropertyMatchingRule">
<injection>
<constructor>
<param name="propertyName" parameterType="string">
<value value="*"/>
</param>
<param name="option" parameterType="PropertyMatchingOption">
<value value="Set" type="PropertyMatchingOption" typeConverter="PropertyMatchingOptionConverter"/>
</param>
</constructor>
</injection>
</matchingRule>
<matchingRule name="DirtyAttributeRule" type="CustomAttributeMatchingRule">
<injection>
<constructor>
<param name="attributeType" parameterType="Type">
<value value="...DirtyAttribute, ..." type="Type" typeConverter="GetTypeConverter"/>
</param>
<param name="inherited" parameterType="bool">
<value value="true" type="bool"/>
</param>
</constructor>
</injection>
</matchingRule>
<matchingRule name="InstanceOfIDirtyRule" type="InstanceOfMatchingRule">
<injection>
<constructor>
<param name="type" parameterType="Type">
<value value="...IDirty, ..." type="Type" typeConverter="GetTypeConverter"/>
</param>
</constructor>
</injection>
</matchingRule>
</matchingRules>
<callHandlers>
<callHandler name="DirtyHandler" type="DirtyHandler"/>
</callHandlers>
</policy>
</policies>
<interceptors>
<interceptor type="VirtualMethodInterceptor">
<key type="Customer"/>
</interceptor>
</interceptors>
</add>
</extensionConfig>
</container>
</containers>
</unity>
</configuration>
The source code of this article can be downloaded here (zip file, 222.26 KB).
I am using Windows Live Writer for posting items to my blog. One thing that I don’t like in general, is that applications store resources in the MyDocuments folder and that you cannot specify another location. I’m a huge fan of portable applications, which means that they don’t need any registry settings and/or dependencies, so that you can simply xcopy deploy to another location. Certainly if you are using an external HD, USB flash drive, etc. Windows Live Writer (WLW) stores by default the drafts in the ‘MyDocuments\My Weblog Posts\Drafts’ folder. I am using the latest beta (v14.0.5025.904) of WLW and didn’t find any settings through the application that enables you to customize folder paths. I decided to dig into the assemblies of WLW via reflector to see how it is implemented. After some investigation I found that there is a class called ApplicationEnvironment that reside in the WindowsLive.Writer.CoreServices assembly. The Initialize method looks like this Apparently WLW has built-in functionality that enables you to run the application with the settings carried around with the software. WLW checks if there is a folder called ‘UserData’ in the installation folder and uses that folder to store all settings, drafts, etc. This is really great, you simply copy all contents of your WLW directory to for example your external drive and you simply create a folder called ‘UserData’. If you start WLW again it will create all the necessary subfolders and settings. I think it’s a feature of WLW beta that has not been documented yet 
With the PDC 08 going on you can download a CTP of Visual Studio 2010.
Cool, Microsoft decided to bring a fresh new .NET logo. The old .NET logo survived for about 8 years. I like the logo very much!

NHibernate uses an xml file to describe the mapping. Typically it is embedded as a resource file inside your project and it has a consistent filename convention, namely <classname>.hbm.xml. Typically an NHibernate project has the following structure  Would it not be nice if we can organize it in the following way? I found it always handy that related classes, like designer classes and resource files are grouped together.  To achieve this structure we can start from the first structure and nest the xml file trough a macro that I’ve written and can be downloaded here (there is also a video how it can be used). The second step, is to make clear to NHibernate where the mapping files reside. Note that resources that are nested to a class are compiled differently and thus NHibernate will not recognize the mapping files anymore. Therefore we need to traverse manually the assembly and try each embedded resource file. Below you find the resulting code var domainAssembly = typeof(MyDomain.Order).Assembly;
NHibernate.Cfg.Configuration cfg = new NHibernate.Cfg.Configuration();
foreach (var resourceName in domainAssembly.GetManifestResourceNames())
{
try
{
cfg.AddResource(resourceName, domainAssembly);
}
catch (NHibernate.MappingException)
{
//ignore
}
}
The unity application block is a dependency injection container with support for constructor, property and method call injection. It simplifies the Inversion of Control (IoC) pattern and the Dependency Injection (DI) pattern. The Unity application block can be found on CodePlex. The unity application block has two important methods for registering types and mappings into the container, namely RegisterType and RegisterInstance. | Method | Default Lifetime | Explanation | | RegisterType | Transient lifetime | Container will create a new instance on each call to Resolve | | RegisterInstance | Container-controller lifetime | Instance has the lifetime of the container | Below you find an example where we map the ILogger interface to ConsoleLogger (implements ILogger). UnityContainer container = new UnityContainer();
container.RegisterType<ILogger, ConsoleLogger>();
ILogger logger = container.Resolve<ILogger>();
Assume you have the following class that contains a dependency to ILogger as a parameter on the constructor. public class MyClass
{
ILogger _logger;
public MyClass(ILogger logger)
{
_logger = logger;
}
}
If we use the Resolve method of UnityContainer it will automatically inject the ILogger (ConsoleLogger) object. This is called constructor injection. UnityContainer container = new UnityContainer();
container.RegisterType<ILogger, ConsoleLogger>();
MyClass myClass = container.Resolve<MyClass>();
You can also map multiple types for the same interface. In that case you can use a key as a parameter. UnityContainer container = new UnityContainer();
container.RegisterType<ILogger, ConsoleLogger>("console");
container.RegisterType<ILogger, EventLogger>("event");
If you now try to resolve MyClass you will get an exception, because it cannot resolve which type (ConsoleLogger or EventLogger) to use. Therefore you can use the Dependency attribute where you can denote a key. For example: public class MyClass
{
ILogger _logger;
public MyClass([Dependency("console")] ILogger logger)
{
_logger = logger;
}
}
Below you find an example of property injection: public class AnotherClass
{
ILogger _consoleLogger;
ILogger _eventLogger;
[Dependency("console")]
public ILogger ConsoleLogger
{
get { return _consoleLogger; }
set { _consoleLogger = value; }
}
[Dependency("event")]
public ILogger EventLogger
{
get { return _eventLogger; }
set { _eventLogger = value; }
}
}
Note that you can also map and register your types through a configuration file. <?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="unity"
type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
Microsoft.Practices.Unity.Configuration" />
</configSections>
<unity>
<containers>
<container>
<types>
<type name="console"
type="IStaySharp.UnitySample.ILogger, IStaySharp.UnitySample"
mapTo="IStaySharp.UnitySample.ConsoleLogger, IStaySharp.UnitySample" />
<type name="event"
type="IStaySharp.UnitySample.ILogger, IStaySharp.UnitySample"
mapTo="IStaySharp.UnitySample.EventLogger, IStaySharp.UnitySample" />
</types>
</container>
</containers>
</unity>
</configuration>
The following code shows you how to use a configuration file with UnityContainer. UnityContainer container = new UnityContainer();
UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
section.Containers.Default.GetConfigCommand().Configure(container);
ILogger logger = container.Resolve<ILogger>("console");
When trying to edit some code during debug, I received the following dialog of Visual Studio: It appears that the edit and continue feature is not supported when the target is a 64-bit application. On this page you find a nice overview of the scenarios where the edit and continue features are not supported. To resolve the problem, you have to set the target to x86, which can be found in the project properties. 
In my current sample project when the runtime tried to access the MyMeta library (see following post) I always get the following FatalExecutingEngineError exception: It turns out that the problem is that the MyMeta library is compiled under a x86 platform whereas the application is running on a x64 platform. In the properties settings of your visual studio project you have to set the platform target to x86! It was set to 'Any CPU', but now everything works fine. 
Component Dropper is a component that resides in the toolbox of VS.NET and enables you to choose a component (controls, datasets, providers, components, etc.) from the assemblies that are referenced in the current project.
In Visual Studio .NET you can auto populate the controls in the toolbox by setting the AutoToolboxPopulate property to true in menu Tools -> Options -> Windows Forms Designer.
Component Dropper is an alternative way for dropping a component on the designer surface. It gives you a dialog with all the components that reside in the assemblies that are referenced in the current project. This means that it is not limited to the assemblies that reside in the current solution. This way you can easily browse and search throughout the assemblies and controls, this is very handy if you have bunch of assemblies and controls. There is never a need to refresh the toolbox, because it dynamically searches throughout the references in the current project.
Download: ComponentDropper v0.9 (35.04 KB)
There is also a demo (1.11 Mb) that illustrates the use of Component Dropper. Note that the demo uses an older version of Component Dropper, namely version 0.5, and it's not an VS add-in anymore.
If after installation you don't see the component dropper appearing in the toolbox, you can simply drag-and-drop the IStaySharp.RazorToolbox.dll to the toolbox. Any suggestions or remarks are welcome!
SMO (SQL Server Management Objects) is a .NET based object library for programming all aspects of managing Microsoft SQL Server. Replication Management Objects (RMO) is another library that encapsulates SQL Server replication management. SMO assemblies are shipped with SQL Server 2005 and can be used to connect with SQL Server 7, 2000 or 2005. The assemblies are located in the following folder C:\Program Files\Microsoft SQL Server\90\SDK\Assemblies. - Microsoft.SqlServer.Smo.dll
- Microsoft.SqlServer.ConnectionInfo.dll
- Microsoft.SqlServer.SmoEnum.dll
- Microsoft.SqlServer.SqlEnum.dll
With SMO you can do all kind of management on a SQL Server, namely: tables, columns, indexes, stored procedures, service broker, backup and restore, managing users/roles and logins, scheduling, etc. Here you can find some specific tasks that can be done with SMO. Below you find an example how you can create a table with SMO: using System.Data.SqlClient;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Common;
public class Sample
{
public void Create(string connectionstring)
{
SqlConnection connection = new SqlConnection(connectionstring);
Server server = new Server(new ServerConnection(connection));
Database database = server.Databases["MyDatabase"];
// Create table, called Customer
Table table = new Table(database, "Customer");
// Add 'ID' column which is the primary key
Column idColumn = new Column(table, "ID");
idColumn.DataType = DataType.Int;
idColumn.Identity = true;
idColumn.IdentitySeed = 1;
idColumn.IdentityIncrement = 1;
// Create a primary key index
Index index = new Index(table, string.Format("PK_{0}", table.Name));
index.IndexKeyType = IndexKeyType.DriPrimaryKey;
index.IndexedColumns.Add(new IndexedColumn(index, "ID"));
table.Indexes.Add(index);
// Add 'Name' column
Column nameColumn = new Column(table, "Name");
nameColumn.DataType = DataType.VarChar(50);
// Add colums to table
table.Columns.Add(idColumn);
table.Columns.Add(nameColumn);
table.Create();
}
}
MyMeta is an open-source API that allows you to get meta-data from your database. MyMeta is part of MyGeneration, a free code generator hosted on Sourceforge. The MyMeta API can be downloaded separately here (filename is called 'mymeta_installer.exe'). MyMeta supports the following databases. Note that the API is extensible and that you can provide your own plug-ins - Advantage
- Delimited Text
- Firebird
- IBM DB2
- IBM iSeries (AS400)
- Interbase
- Microsoft Access
- Microsoft SQL CE
- Microsoft SQL Server
| - MySQL
- MySQL2
- Oracle
- Pervasive
- PostgreSQL
- PostgreSQL 8+
- SQLite
- VistaDB
- Xsd3b (xml,xsd,uml,er)
| Below you find a code snippet that will iterate, for a SQLite database, all tables, columns and indexes. string connectionstring = @"data source=SQLiteDatabase.DB";
MyMeta.dbRoot myMeta = new MyMeta.dbRoot();
myMeta.Connect(MyMeta.dbDriver.SQLite, connectionstring);
IDatabase db = myMeta.DefaultDatabase;
foreach (MyMeta.ITable table in db.Tables)
{
Console.WriteLine("{0} ({1})", table.Name, table.Columns.Count);
Console.WriteLine("\tCOLUMNS");
foreach (MyMeta.IColumn column in table.Columns)
{
Console.WriteLine("\t\t{0} ({1}), Nullable:{2}",
column.Name, column.DataTypeName, column.IsNullable);
}
Console.WriteLine("\tINDEXES");
foreach (MyMeta.IIndex index in table.Indexes)
{
Console.WriteLine("\t\t{0}, Unique:{1}", index.Name, index.Unique);
}
}
MyMeta can map database types to specific ADO.NET data types and language types (C#, VB.NET, etc.). MyMeta has a set of XML files (included in the setup) that contains these mappings. Namely the 'Languages.xml' and 'DbTargets.xml'. Below you find a snippet of the two XML files:
<Languages>
...
<Language From="SQL" To="C#">
<Type From="bigint" To="long" />
<Type From="binary" To="object" />
<Type From="bit" To="bool" />
<Type From="char" To="string" />
<Type From="datetime" To="DateTime" />
<Type From="decimal" To="decimal" />
<Type From="float" To="double" />
<Type From="image" To="byte[]" />
<Type From="int" To="int" />
<Type From="money" To="decimal" />
<Type From="nchar" To="string" />
<Type From="ntext" To="string" />
<Type From="numeric" To="decimal" />
<Type From="nvarchar" To="string" />
<Type From="real" To="float" />
<Type From="smalldatetime" To="DateTime" />
<Type From="smallint" To="short" />
<Type From="smallmoney" To="decimal" />
<Type From="text" To="string" />
<Type From="timestamp" To="byte[]" />
<Type From="tinyint" To="byte" />
<Type From="uniqueidentifier" To="Guid" />
<Type From="varbinary" To="byte[]" />
<Type From="varchar" To="string" />
<Type From="xml" To="string" />
<Type From="sql_variant" To="object" />
</Language>
...
<Language From="SQLITE" To="C# (SQLite v3.x)">
<Type From="CHAR" To="string" />
<Type From="DATETIME" To="DateTime" />
<Type From="DATE" To="DateTime" />
<Type From="TIMESTAMP" To="DateTime" />
<Type From="TIME" To="TimeSpan" />
<Type From="DECIMAL" To="decimal" />
<Type From="VARCHAR" To="string" />
<Type From="NVARCHAR" To="string" />
<Type From="TEXT" To="string" />
<Type From="INTEGER" To="long" />
<Type From="INT" To="long" />
<Type From="FLOAT" To="float" />
<Type From="BOOLEAN" To="bool" />
<Type From="CLOB" To="string" />
<Type From="BLOB" To="byte[]" />
<Type From="NUMERIC" To="decimal" />
<Type From="VARYINGCHARACTER" To="string" />
<Type From="NATIONALVARYINGCHARACTER" To="string" />
</Language>
...
</Languages>
|
<DbTargets>
...
<DbTarget From="SQL" To="SqlClient">
<Type From="bigint" To="SqlDbType.BigInt" />
<Type From="binary" To="SqlDbType.Binary" />
<Type From="bit" To="SqlDbType.Bit" />
<Type From="char" To="SqlDbType.Char" />
<Type From="datetime" To="SqlDbType.DateTime" />
<Type From="decimal" To="SqlDbType.Decimal" />
<Type From="float" To="SqlDbType.Float" />
<Type From="image" To="SqlDbType.Image" />
<Type From="int" To="SqlDbType.Int" />
<Type From="money" To="SqlDbType.Money" />
<Type From="nchar" To="SqlDbType.NChar" />
<Type From="ntext" To="SqlDbType.NText" />
<Type From="numeric" To="SqlDbType.Decimal" />
<Type From="nvarchar" To="SqlDbType.NVarChar" />
<Type From="real" To="SqlDbType.Real" />
<Type From="smalldatetime" To="SqlDbType.SmallDateTime" />
<Type From="smallint" To="SqlDbType.SmallInt" />
<Type From="smallmoney" To="SqlDbType.SmallMoney" />
<Type From="text" To="SqlDbType.Text" />
<Type From="timestamp" To="SqlDbType.Timestamp" />
<Type From="tinyint" To="SqlDbType.TinyInt" />
<Type From="uniqueidentifier" To="SqlDbType.UniqueIdentifier" />
<Type From="varbinary" To="SqlDbType.VarBinary" />
<Type From="varchar" To="SqlDbType.VarChar" />
<Type From="xml" To="SqlDbType.Xml" />
<Type From="sql_variant" To="SqlDbType.Variant" />
</DbTarget>
...
<DbTarget From="SQLITE" To="SQLite.NET v3.x">
<Type From="CHAR" To="DbType.String" />
<Type From="DATETIME" To="DbType.DateTime" />
<Type From="DATE" To="DbType.DateTime" />
<Type From="TIMESTAMP" To="DbType.DateTime" />
<Type From="TIME" To="DbType.Time" />
<Type From="DECIMAL" To="DbType.Decimal" />
<Type From="VARCHAR" To="DbType.String" />
<Type From="NVARCHAR" To="DbType.String" />
<Type From="TEXT" To="DbType.String" />
<Type From="INTEGER" To="DbType.Int64" />
<Type From="INT" To="DbType.Int32" />
<Type From="FLOAT" To="DbType.Single" />
<Type From="BOOLEAN" To="DbType.Boolean" />
<Type From="CLOB" To="DbType.String" />
<Type From="BLOB" To="DbType.Binary" />
<Type From="NUMERIC" To="DbType.Decimal" />
<Type From="VARYINGCHARACTER" To="DbType.String" />
<Type From="NATIONALVARYINGCHARACTER" To="DbType.String" />
</DbTarget>
...
</DbTargets>
|
The xml files can be loaded by setting the LanguageMappingFilename and DbTargetMappingFilename. Setting the right target can be done by the properties Language and DbTarget. string connectionstring = @"data source=SQLiteDatabase.DB";
MyMeta.dbRoot myMeta = new MyMeta.dbRoot();
myMeta.Connect(MyMeta.dbDriver.SQLite, connectionstring);
myMeta.LanguageMappingFileName = @"C:\Program Files\MyGenerations\Settings\Languages.xml";
myMeta.DbTargetMappingFileName = @"C:\Program Files\MyGenerations\Settings\DbTargets.xml";
myMeta.Language = "C# (SQLite v3.x)";
myMeta.DbTarget = "SQLite.NET v3.x";
IDatabase db = myMeta.DefaultDatabase;
foreach (MyMeta.ITable table in db.Tables)
{
Console.WriteLine("{0} ({1})", table.Name, table.Columns.Count);
Console.WriteLine("\tCOLUMNS");
foreach (MyMeta.IColumn column in table.Columns)
{
Console.WriteLine("\t\t{0} ({1}), DBTargetType:{2}, LanguageType:{3}",
column.Name, column.DataTypeName, column.DbTargetType, column.LanguageType);
}
}
The mapped types can be found in the properties DbTargetType and LanguageType on the IColumn interface.
I has been a while that I released a new version of ComponentDropper and I am going to release a new update very soon. I received positive feedback, and I am planning to add some new features and certainly to provide an installer for the add-in. Please leave a comment if you have any suggestions about ComponentDropper.
On my current project I had the need to iterate through the properties of an object with reflection and to check if one of the properties is a generic List type, e.g. IList<int>, IList<Customer>, etc. To check through reflection on a generic type, you need to use the GetGenericTypeDefinition method. foreach (PropertyInfo propertyInfo in entity.GetType().GetProperties())
{
if (propertyInfo.PropertyType.IsGenericType &&
typeof(List<>).IsAssignableFrom(propertyInfo.PropertyType.GetGenericTypeDefinition()))
{
IEnumerable enumerable = propertyInfo.GetValue(entity, null) as IEnumerable;
IEnumerator enumerator = enumerable.GetEnumerator();
while (enumerator.MoveNext())
{
// do something
}
}
}
CSLA.NET framework from Lhotka contains a lot of mechanisms for adding validations and business rules. Through CSLA.NET you can easily provide your own custom rules. Enterprise Library v3.0 now also contains a validation application block (VAB) that can be used through attributes and even from a configuration file. The two validation mechanisms of validation are complementary. This can be done by adding a custom rule that uses the ValidationFactory of the VAB. This means we have something like: public class VABRules
{
public class VABRuleArgs : RuleArgs
{
private string _ruleset;
public string Ruleset
{
get { return _ruleset; }
}
public VABRuleArgs(string propertyName) : this(propertyName, null)
{
}
public VABRuleArgs(string propertyName, string ruleset) : base(propertyName)
{
_ruleset = ruleset;
}
}
public static bool VABValid<T>(object target, RuleArgs e)
{
Validator<T> validator = ValidationFactory.CreateValidator<T>(((VABRuleArgs)e).Ruleset);
if (validator == null)
return true;
ValidationResults results = validator.Validate(target);
if (results == null)
return true;
foreach (ValidationResult result in results)
{
if (result.Key == e.PropertyName)
{
e.Description = result.Message;
return false;
}
}
return true;
}
}
Having the VAB rule we simply need to decorate our properties with the validation attributes of VAB and an override of the AddBusinessRules method is needed to take into account the VAB rules. For example we can define a customer business object as follow:
[Serializable()]
public class Customer : Csla.BusinessBase<Customer>
{
private int _id = 0;
private string _firstName = string.Empty;
private string _email = string.Empty;
private int _rewardPoints;
private string _countryCode = string.Empty;
[Browsable(false), System.ComponentModel.DataObjectField(true, true)]
public int Id
{
get
{
CanReadProperty("Id", true);
return _id;
}
}
[NotNullValidator(MessageTemplate="First Name may not be empty")]
[StringLengthValidator(1, 60, MessageTemplate = "First Name must be between 1 and 60 characters long")]
public string FirstName
{
get
{
CanReadProperty("FirstName", true);
return _firstName;
}
set
{
CanWriteProperty("FirstName", true);
if (!_firstName.Equals(value))
{
_firstName = value;
PropertyHasChanged("FirstName");
}
}
}
[RegexValidator(@"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*")]
public string Email
{
get
{
CanReadProperty("Email", true);
return _email;
}
set
{
CanWriteProperty("Email", true);
if (!_email.Equals(value))
{
_email = value;
PropertyHasChanged("Email");
}
}
}
[Int32RangeValidator(0, 1000000, MessageTemplate = "Rewards points cannot exceed 1,000,000")]
public int RewardPoints
{
get
{
CanReadProperty("RewardPoints", true);
return _rewardPoints;
}
set
{
CanWriteProperty("RewardPoints", true);
if (!_rewardPoints.Equals(value))
{
_rewardPoints = value;
PropertyHasChanged("RewardPoints");
}
}
}
[NotNullValidator(MessageTemplate = "Country may not be empty")]
public string CountryCode
{
get
{
CanReadProperty("CountryCode", true);
return _countryCode;
}
set
{
CanWriteProperty("CountryCode", true);
if (!_countryCode.Equals(value))
{
_countryCode = value;
PropertyHasChanged("CountryCode");
}
}
}
protected override object GetIdValue()
{
return _id;
}
protected override void AddBusinessRules()
{
ValidationRules.AddRule(VABRules.VABValid<Customer>, new VABRules.VABRuleArgs("FirstName"));
ValidationRules.AddRule(VABRules.VABValid<Customer>, new VABRules.VABRuleArgs("Email"));
ValidationRules.AddRule(VABRules.VABValid<Customer>, new VABRules.VABRuleArgs("RewardPoints"));
ValidationRules.AddRule(VABRules.VABValid<Customer>, new VABRules.VABRuleArgs("CountryCode"));
}
}
In many enterprise applications there is the need that, regardless on which control you have the focus, that you can hit the 'Enter' and/or 'Esc' key to perform a default action. This behaviour is also common to web applications. On the Form control you find properties like AcceptButton and CancelButton, whereas the UserControl doesn't have these properties. The code below contains an AcceptButton and CancelButton that allows you to define a default action when the Enter or Esc key is pressed respesctively. public class UserControlEx : System.Windows.Forms.UserControl
{
private Button _acceptButton;
private Button _cancelButton;
public event EventHandler<EventArgs> AcceptEvent;
public event EventHandler<EventArgs> CancelEvent;
[Browsable(true)]
public Button AcceptButton
{
get { return _acceptButton; }
set { _acceptButton = value; }
}
[Browsable(true)]
public Button CancelButton
{
get { return _cancelButton; }
set { _cancelButton = value; }
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (msg.WParam.ToInt32() == (int)Keys.Enter)
{
OnAcceptEvent(EventArgs.Empty);
if (_acceptButton != null)
_acceptButton.PerformClick();
}
if (msg.WParam.ToInt32() == (int)Keys.Escape)
{
OnCancelEvent(EventArgs.Empty);
if (_cancelButton != null)
_cancelButton.PerformClick();
}
return base.ProcessCmdKey(ref msg, keyData);
}
protected virtual void OnAcceptEvent(EventArgs args)
{
if (AcceptEvent != null)
AcceptEvent(this, args);
}
protected virtual void OnCancelEvent(EventArgs args)
{
if (CancelEvent != null)
CancelEvent(this, args);
}
}
In some enterprise applications you need to show geographical data such as countries and postcodes. Most of the time you need it for a registration page, where the user need to fill in the country and postcode/area. Geonames is a free geographical database that contains over 8 million geographical names and it can be accessed through a number of webservices. For example the url http://ws.geonames.org/countryInfo? gives an xml with all countries, whereas the following request http://ws.geonames.org/postalCodeSearch?placename=be gives us all postcodes for a particular country (e.g. Belgium). Most likely you need two dropdown lists, one for countries and one for postcodes, where the postcode dropdown is dependent from the country dropdown list. This is a very good example to introduce AJAX by using the CascadingDropdown that is included in ASP.NET AJAX. To implement this functionality we need to implement two methods on a webservice, namely GetCountries and GetPostalCodesByCountry. The GetCountries simply returns all countries sorted by name and looks like this: [WebMethod]
public CascadingDropDownNameValue[] GetCountries()
{
List<CascadingDropDownNameValue> list = new List<CascadingDropDownNameValue>();
CountryItemCollection countries = IStaySharp.Geonames.GeonamesService.GetAllCountries();
for (int i = 0; i < countries.Countries.Length; i++)
{
list.Add(new CascadingDropDownNameValue(
countries.Countries[i].CountryName,
countries.Countries[i].CountryCode));
}
list.Sort(CompareCascadingDropDownNameValueByName);
return list.ToArray();
}
Note that the list need to be converted to an array of CascadingDropDownNameValue objects. Note that we also sort the list by implementing a delegate named CompareCascadingDropDownNameValueByName. private static int CompareCascadingDropDownNameValueByName(CascadingDropDownNameValue x, CascadingDropDownNameValue y)
{
if (x == null && y == null)
return 0;
else if (x == null && y != null)
return -1;
else if (x != null && y == null)
return 1;
else
return x.name.CompareTo(y.name);
}
The other webservice method, called GetPostalCodesByCountry, need to retrieve all postcodes for a particular country. The signature of the method is very strict. The parameter names must be named 'knownCategoryValues' and 'category', otherwise it will fail! [WebMethod]
public CascadingDropDownNameValue[] GetPostalCodesByCountry(string knownCategoryValues, string category)
{
List<CascadingDropDownNameValue> list = new List<CascadingDropDownNameValue>();
StringDictionary kv = CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues);
if (kv.ContainsKey("Country"))
{
string countryName = kv["Country"];
PostalCodeItemCollection postalCodes = IStaySharp.Geonames.GeonamesService.GetPostalCodes(countryName);
for (int i = 0; i < postalCodes.PostalCodes.Length; i++)
{
list.Add(new CascadingDropDownNameValue(
string.Format("{0} ({1})", postalCodes.PostalCodes[i].PostalCode, postalCodes.PostalCodes[i].Name),
postalCodes.PostalCodes[i].PostalCode));
}
}
list.Sort(CompareCascadingDropDownNameValueByName);
return list.ToArray();
}
In order to complete the webservice, the attribute ScriptService (line 3) need to be included so that a client javascript proxy can be generated. You can test this by calling your webservice like this http://localhost:9999/GeonamesService.asmx/js. [WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService()]
public class GeonamesService : System.Web.Services.WebService
{
...
}
Finally we only need to add two CascadingDropDown controls on our aspx page with the following settings: <asp:ScriptManager ID="scriptManager" runat="server" />
<asp:DropDownList ID="countriesDropDown" runat="server"/>
<ajaxToolkit:CascadingDropDown
ID="countriesCascadingDropDown"
TargetControlID="countriesDropDown"
Category="Country"
PromptText="Please select a country"
LoadingText="[Loading countries...]"
ServicePath="/GeonamesService.asmx"
ServiceMethod="GetCountries"
runat="server"/>
<br/><br/>
<asp:DropDownList ID="postalCodesDropDown" runat="server"/>
<ajaxToolkit:CascadingDropDown
ID="postalCodesCascadingDropDown"
TargetControlID="postalCodesDropDown"
Category="PostalCode"
PromptText="Please select postalcode"
LoadingText="[Loading postalcodes...]"
ServicePath="GeonamesService.asmx"
ServiceMethod="GetPostalCodesByCountry"
ParentControlID="countriesDropDown"
runat="server"/>
The source code can be downloaded here: IStaySharp.AJAXSample.rar (332,56 KB)
Scott Guthrie is coming for a presentation on February 1st. The session will take place at Utopolis Mechelen. Please subscribe to the event through the VISUG site. Two presentations will be given, namely: - First Look at Visual Studio and ASP.NET 'Orcas'
- ASP.NET 2.0 and ASP.NET AJAX Tips and Tricks
See you there!
Virtual PC 2007 RC1 has been released, and can be downloaded on the Microsoft Connect site, if you participated in the beta tests. The main new features are:
- Support for Windows Vista™ as a host operating system
- Support for Windows Vista™ as a guest operating system
- Support for 64-bit host operating systems
- Support for hardware-assisted virtualization
- Built-in support for network installations
More details about the release notes can also be downloaded on the Microsoft Connect site.
The Validation Application Block (VAB) of the upcoming Enterprise Library v3, uses attributes to describe validations. This gives us for example the opportunity to generate ASP.NET validators based on the attributes decorated on the properties. Take for example the NotNullValidator of VAB, this can be translated to a RequiredFieldValidator, whereas the RegexValidator can be translated to RegularExpressionValidator. You can go further with the NotNullValidator and mark required fields with a different backcolor and adding an asterix (*) to the end of the control. I am big fan of the DetailsView control, you can simply bind a DataSource control to it, and it will automatically provide you with a caption to each control and two-way binding. Below you find an example how you can extend the BoundField control, that investigates the NotNullValidator attribute of VAB. Note that I am currently extending it for the other set of validators and in a more OO way. More info will follow later. public class BoundFieldEx : System.Web.UI.WebControls.BoundField
{
public override void InitializeCell(
DataControlFieldCell cell, DataControlCellType cellType,
DataControlRowState rowState, int rowIndex)
{
base.InitializeCell(cell, cellType, rowState, rowIndex);
if ((((rowState & DataControlRowState.Edit) != DataControlRowState.Normal) && !this.ReadOnly) ||
((rowState & DataControlRowState.Insert) != DataControlRowState.Normal))
{
TextBox textBox = null;
if (cell != null && cell.Controls.Count > 0)
textBox = cell.Controls[0] as TextBox;
if (textBox != null)
{
Type dataItemType = null;
if (DataBinder.GetDataItem(base.Control) != null)
dataItemType = DataBinder.GetDataItem(base.Control).GetType();
if (dataItemType != null)
{
ValidatorAttribute attribute = IsRequired(dataItemType, base.DataField);
if (attribute != null)
{
string textBoxID = this.DataField;
textBox.ID = textBoxID;
RequiredFieldValidator validator = new RequiredFieldValidator();
validator.ControlToValidate = textBoxID;
validator.ID = string.Concat("RequiredValidatorOf", textBoxID);
validator.Display = ValidatorDisplay.Dynamic;
validator.ErrorMessage = attribute.MessageTemplate;
cell.Controls.Add(validator);
}
}
}
}
}
private ValidatorAttribute IsRequired(Type dataType, string property)
{
PropertyInfo propertyInfo = dataType.GetProperty(property);
if (propertyInfo != null)
{
foreach (Attribute attribute in propertyInfo.GetCustomAttributes(true))
{
if (attribute is NotNullValidatorAttribute)
return attribute as ValidatorAttribute;
}
}
return null;
}
}
Now you create a custom business object, called Customer, and bind it to the DetailsView through an ObjectDataSource. public class Customer
{
private string _firstName;
private string _lastName;
[NotNullValidator(MessageTemplate="Firstname cannot be empty")]
public string FirstName
{
get { return _firstName; }
set { _firstName = value; }
}
[NotNullValidator(MessageTemplate="Lastname cannot be empty")]
public string LastName
{
get { return _lastName; }
set { _lastName = value; }
}
public Customer Fill()
{
Customer customer = new Customer();
customer.FirstName = "Christoph";
customer.LastName = "De Baene";
return customer;
}
}
Inside your aspx page you have something like <asp:ObjectDataSource id="customerDataSource"
TypeName="IStaySharp.Business.Customer, IStaySharp.Business"
DataObjectTypeName="IStaySharp.Business.Customer, IStaySharp.Business"
SelectMethod="Fill"
runat="server">
</asp:ObjectDataSource>
<asp:ValidationSummary runat="server"/>
<asp:DetailsView DataSourceID="customerDataSource" DefaultMode="Edit" AutoGenerateRows="false" runat="server">
<Fields>
<rfx:BoundField HeaderText="Firstname" DataField="FirstName"/>
<rfx:BoundField HeaderText="Lastname" DataField="LastName"/>
</Fields>
</asp:DetailsView>
Here is the result if you leave the properties empty:

Tom Hollander revealed some features/scenarios about the upcoming Validation Application Block that will be included in Enterprise Library v3. There are already some validation libraries available, for example The fact that you can define rules through configuration is really cool. I can't wait for the CTP!
VISUG has a brand new website. All the necessary features are already available and more functionality is coming soon. The two last VISUG events for year 2006 are announced. One of the events is a panel discussion about exception handling and logging, and it will take place at Real Software (my home). The other event is a geek dinner where we can discuss about... you know what I mean ;). Topic: Discussion on Enterprise Exception Handling and Logging
Description: This is a session where you (yes, you!) can discuss exception handling and logging in enterprise applications. Bring your tips and tricks, problems and exception handling frustrations with you, and we'll all learn about best practices together! No slides or preparation required! Don't want to discuss? No problem, you're not required to say anything, but we hope you will. To help with a smooth discussion, it will be lead by a panel of 3 to 4 people. If you're interested to sit on this panel, you're invited (First-come, First-served basis).
When: Monday 11 December, 18:30 - 20:30
Where: Real Software (Prins Boudewijnlaan, 2550 Kontich, Route) Register: VISUG website
See you on both events!
This macro enables you to nest project items inside Visual Studio .NET. Until now, there is no easy way to nest project items through the Visual Studio IDE, you can only do it by manipulating the project (.csproj or .vbproj) file and adding the DependentUpon element.

Inside the IStaySharp.vsmacros file there is a macro called 'Create Dependency' which allows you to nest two selected items. I have even created a video (672,18 KB) to illustrate how to configure and use the macro.
PowerShell 1.0 has been released for Windows XP SP2 and Windows Server 2003. The bits can be downloaded here. If you already have installed a previous release of PowerShell, you need to uninstall by selecting 'Show Updates' in the 'Change or Remove Programs'. 
I am currently building software factories and I needed a way to have a list of running Visual Studio instances and the corresponding EnvDTE._DTE object to manipulate the solution. Windows internally keeps a list of COM objects that are currently running, called the Running Object Table (ROT). VS .NET 2005 for example, register itself in the ROT as "!VisualStudio.DTE.8.0:pid" where 'pid' is the process id of the corresponding VS 2005 instance. In .NET 1.1 you would use the the following UCOMIRunningObjectTable, UCOMIBindCtx for enumerating the ROT. In .NET 2.0 these interfaces are obsolete and are replaced by IRunningObjectTable and BIND_OPTS respectively. Note that the same code can be used for getting other instances like MS Word, IE, etc. using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using EnvDTE;
public static class DTEHelper
{
const uint S_OK = 0;
[DllImport("ole32.dll")]
public static extern uint GetRunningObjectTable(uint reserved, out IRunningObjectTable ROT);
[DllImport("ole32.dll")]
public static extern uint CreateBindCtx(uint reserved, out IBindCtx ctx);
static IDictionary<string, object> GetRunningObjectTable()
{
IDictionary<string, object> rotTable = new Dictionary<string, object>();
IRunningObjectTable runningObjectTable;
IEnumMoniker monikerEnumerator;
IMoniker[] monikers = new IMoniker[1];
GetRunningObjectTable(0, out runningObjectTable);
runningObjectTable.EnumRunning(out monikerEnumerator);
monikerEnumerator.Reset();
IntPtr numberFetched = IntPtr.Zero;
while (monikerEnumerator.Next(1, monikers, numberFetched) == 0)
{
IBindCtx ctx;
CreateBindCtx(0, out ctx);
string runningObjectName;
monikers[0].GetDisplayName(ctx, null, out runningObjectName);
Marshal.ReleaseComObject(ctx);
object runningObjectValue;
runningObjectTable.GetObject(monikers[0], out runningObjectValue);
if (!rotTable.ContainsKey(runningObjectName))
rotTable.Add(runningObjectName, runningObjectValue);
}
return rotTable;
}
public static IDictionary<string, _DTE> GetRunningVSIDETable()
{
IDictionary<string, object> runningObjects = GetRunningObjectTable();
IDictionary<string, _DTE> runningDTEObjects = new Dictionary<string, _DTE>();
foreach (string objectName in runningObjects.Keys)
{
if (!objectName.StartsWith("!VisualStudio.DTE"))
continue;
_DTE ide = runningObjects[objectName] as _DTE;
if (ide == null)
continue;
runningDTEObjects.Add(objectName, ide);
}
return runningDTEObjects;
}
}
The Microsoft Patterns & Practicess Team recently released a new version of the Web Client Software Factory that can be found on CodePlex. One of the things I noticed directly, is that they implemented a web version of the Composite UI based on the ObjectBuilder. The goals of Web Client Software Factory are: - CAB for Web
- Hiding complexity
- Separation of infrastructure & biz logic
- Biz logic reuse amongst different UI Technologies
- Promoting consistent development practices
- Navigation
- UI Richness
- UI Layout management
- State management
- Best use of technology available (Ajax, WinForms controls, ...)
- Security
- SaaS implications on application design
More information about the vision & scope can be found here.
On IStaySharp.NET I created an article that shows you, how you can load a DSL file. This is necessary if you need to access your model from GAT, a Visual Studio AddIn, custom library, etc. The last couple of weeks I am digging into DSL and GAT for creating a set of software factories at Real Software that will be used as a baseline for building applications. Learning two (DSL & GAT) simultaneously and combining them was not so trivial and there is some learning curve. For GAT there are some interesting resources: The MSDN forums is a good resource when you have some issues and/or questions. DSL has also a specific forum. The capabilities of DSL are really impressive. Now you have finally the tools to write for example your own dataset designer with code generation!!!
I've upgraded SyntaxColor4Writer with the new version of CodeHighlighter 4.0. It uses a new parsing model and it supports some additional language definitions, namely: For example: HasChanges method of a DataSet in MSIL - Copy Code1 .method public hidebysig instance bool HasChanges() cil managed
2 {
3 .maxstack 2
4 L_0000: ldarg.0
5 L_0001: ldc.i4.s 28
6 L_0003: call instance bool System.Data.DataSet::HasChanges(System.Data.DataRowState)
7 L_0008: ret
8 }
Any suggestions and/or feedback about SyntaxColor4Writer is welcome!
A new version of CruiseControl.NET has been released. The release notes of version 1.1 can be found here. This is the defacto standard tool if you want to continuous integration together with unit testing, code metrics, code analysis, etc.
Today I published a new version of SyntaxColor4Writer on IStaySharp.NET. It's compiled against the new beta version of Windows Live Writer with the following added features: - 'Copy Code' link (copies everything to the clipboard)
- Caption text
- Customize backcolor, including line numbering
- Spaces in tabs
- Font size
Below you find some examples: 1 <system.web>
2 <compilation defaultLanguage="VB" debug="true"/>
3 <customErrors mode="ReadOnly"/>
4 </system.web>
C# code of the Main method class.
Program.cs - Copy Code 1 /// <summary>
2 /// The main entry point for the application.
3 /// </summary>
4 [STAThread]
5 static void Main()
6 {
7 Application.EnableVisualStyles();
8 Application.SetCompatibleTextRenderingDefault(false);
9 Application.Run(new TestForm());
10 }
Cassini is a ASP.NET sample application that shows how to write a web server using .NET. This means that you can host ASP.NET using the ASP.NET hosting APIs (System.Web.Hosting). This is really an alternative to IIS. There is also a second project called UltiDev Cassini Web Server which is based on the Cassini source with the following additional features:
- Comes ready for distribution with Visual Studio ASP.NET applications
- Runs as a windows service
- Hosts and runs multiple ASP.NET applications
- Provides management UI and simple API for configuring web applications
- Comes in two flavors: 2.0 version for ASP.NET 2.0 applications, and 1.1 for applications compiled for ASP.NET 1.1
If you have the need for an offline version of your ASP.NET application, where easy deployment is required (without IIS), then this is a very good solution.
DasBlog 1.9 is released. It's a major update with a lot of extra features and fixes. I contributed to this release for improving DasBlog in a multi-user setup. The following features has been added (will update the documentation on dasblog.info):
- Top Posters macro & Profile Combo control
- Every admin/contributor can create/edit a personal profile page
- A Contributor can be notified by mail for certain events and can be configured through the 'User Settings' screen
- Notify when a new post has been added
- Notify when comments has been added for ALL posts
- Notify when comments has been added for OWN posts
I also created a new theme called 'business', which is running on my weblog now. It's not yet included in this release, but it's available through the subversion repository. I am also planning to create a theme, based on 'business', for in a multi-user setup.
Soon I will update RealDN (corporate blog of my company I am working for) to DasBlog 1.9.
Windows Live Writer is a desktop application that makes it easier to compose compelling blog posts using Windows Live Spaces or your current blog service. For Windows Live Writer I created a plugin called SyntaxColor4Writer that enables you to embed syntax highlighting in your blog posts. More details about SyntaxColor4Writer can be found here. This is how the plugin looks:
This is an example of a xml fragment generated by SyntaxColor4Writer:
<system.web>
<compilation defaultLanguage="VB" debug="true" />
<customErrors mode="RemoteOnly" />
</system.web>
That's right, a public preview of Office 2007 Beta 2 is available. You can download the bits from here. Note that right now it is very difficult to connect to the server, due to high traffic.
BindingListView<T> is a project hosted on GotDotNet that gives you search, sorting and filtering capabilities to a plain BindingList. For example if you have the following Person entity: public class Person
{
string firstName = string.Empty;
int age = 0;
public string FirstName
{
get { return firstName; }
set { firstName = value; }
}
public int Age
{
get { return age; }
set { age = value; }
}
public Person(string firstName, int age)
{
this.firstName = firstName;
this.age = age;
}
}
And you want to have a collection of persons bind to a datagrid, you can simply write the following: BindingList<Person> persons = new BindingList<Person>();
persons.Add(new Person("Bill", 45));
persons.Add(new Person("Gert", 33));
persons.Add(new Person("Johan", 12));
persons.Add(new Person("An", 27));
personsGrid.DataSource = persons;
What if you need to do some filtering, or simply sorting on the datagrid? Therefore you would need to create a custom collection class that implements a bunch of interfaces for having sorting, filtering and searching capabilities.
The BindingListView<T> class has all these functionalities built-in. You simply have to pass a list, and bind the BindingListView to the datagrid. The same way you would do with a DataSet and DataView. This means: BindingListView<Person> personsView = new BindingListView<Person>(persons);
personsGrid.DataSource = personsView;
Sorting on a BindingListView is done through the Sort property, the same as on a DataView. For example: personsView.Sort = "FirstName";
Filtering is done through the Filter property and uses anonymous delegates. So for example to filter all persons that are less than 30, you can write: personsView.Filter = BindingListView<Person>.CreateItemFilter(new Predicate<Person>(
delegate(Person person)
{
return (person.Age < 30);
}
));
You can also merge multiple sources to one view (functionality that the DataView doesn't support) through the AggregatedBindingListView<T>.
One of the ways for extending the WebBrowser 2.0 control is to inherit from WebBrowserSiteBase. According to the documentation, you have to override the method CreateWebBrowserSiteBase and return your specific implementation of WebBrowserSiteBase.
Everything is there to plug-in your implementation of WebBrowserSiteBase, but the problem is that the constructor of WebBrowserSiteBase is marked as internal, and so there is no way to inherit from. I am pretty sure that it was possible with the beta release of .NET 2.0, but for some reason they marked it as internal in the RTM version. This means that implementing some interfaces that are described here are not possible.
I am planning to release a .NET 2005 version of my IStaySharp.WebBrowser project. More info coming soon.
The Service Factory is a cohesive collection of various forms of guidance that have been build with the primary goal of helping you build high quality connected solutions in a more consistent way with less effort.
Check it out: http://practices.gotdotnet.com/projects/svcfactory
Finally I have updated my site, called IStaySharp to MediaWiki. MediaWiki is one of the best wiki based engines available and it's written in PHP and MySQL. Thankfully my hosting, webhost4life, has PHP & MySQL support. The intention of IStaySharp is to document and archive my code snippets, articles, components, projects, etc. that I am working on, and to share my experiences that I encounter during my .NET development. Visitors to the site can use the discussion page to give feedback, remarks, suggestions, etc. to the associated page. I didn't encounter much problems when installing MediaWiki on webhost4life, except the e-mailing didn't work directly. The problem was that MediaWiki uses the format: 'myname <myname@domain.com>' in the 'to' field of the mail function, and with the current settings and setup of webhost4life this resulted in an invalid address. Therefore I had to change the method 'toString()' of the 'MailAddress' class inside 'UserMailer.php' to function toString()
{
return $this->address;
}
instead of function toString()
{
if( $this->name != '' ) {
return wfQuotedPrintable( $this->name ) . " <" . $this->address . ">";
} else {
return $this->address;
}
}
IStaySharp uses also the extension that I wrote for having syntax highlighting. Some other nice extensions are coming!
When reviewing code, you see a lot of 'bad' use of exception handling. As Pieter Gheysens mentioned, you see a lot of code that looks like: try
{
// code statements
}
catch(Exception exc)
{
throw exc;
}
No extra logic defined inside the catch-block, like logging, and when it is meant to re-throw an exception, the 'throw' statement must be used, instead of 'throw ex'. The statement 'throw ex' will erase the original stacktrace. Best practice for exception handling is
try
{
// code that could throw an exception
}
catch(Exception exc)
{
// log exception
throw;
}
In case of a traditional layered architecture, UI, Business Logic (BL) & Data Access Logic (DAL), you will catch a DAL exception inside the BL layer, and translate it to a 'meaningfull' business exception. Each layer has a specific purpose and domain, and so are the exceptions!
It's also a good idea to subscribe to the Application.ThreadException (in case of a form application) and do the logging in there. Here log4net is used as logging tool. ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
log.Error("Application error", e.Exception);
// show custom error dialog or throw
}
Modern GPUs are increasing in programmability and these chips can do more than just graphical computations. They can now be used as a coprocessor, and they can be integrated for a set of tasks. GPGPU (General-Purpose compuation on GPUs) is such an initiative that contains a catalog where the GPU can be used for general-purpose computation.
The big challenge, is to translate the everyday applications to two-dimensional graphic functions, like texture mapping. In other words: Pretend that everything is a game (source).
As an example in this article and results, a quicksort algorithm of 18 million records in Visual C++ took 21 seconds, while the GPU took 2 seconds! What are the results for a Quad SLI setup? 
Microsoft research is apparently working on a system that simplifies the programming of GPU to general-purpose tasks, it's called Accelerator (simplified programming of graphics processing units for general-purpose uses via data-parallelism).
Continuous integration is the process that continuously build, analyze and test your sources. In many cases the process is triggered when changes are notified in the version control system, like VSS, CVS, etc. Martin Fowler has a good article about continuous integration.
In the .NET world, the most famous tool is CruiseControl.NET in combination with NAnt & NUnit. Getting an e-mail or popup from CruiseControl.NET is nice when a build is broken, but notifying the build status through traffic lights is much cooler.
Michael Swanson integrated CC.NET with the Ambient Orb. I think that the Ambient Orb is not an option for Europe, but you can integrate by using the X10 home automation technology. A good article about integrating X10 with .NET can be found on Coding4Fun and is called Controlling Lights with .NET.
Here are some (other) implementations:
I am going for a walk this evening, and I think that tomorrow a traffic light will be missing

CAB is an application block for building smart clients in .NET 2.0 and contains proven practices for building complex UI forms with so called SmartParts and Workspaces. The DeckWorkspace enables you to show and hide controls and SmartParts in an overlapped manner with no visible frame. If you switch between controls, you will notice that the controls are painted while there are initializing. During the loading you will see that there is some overlapping and it doesn't give you a professional user experience.  Therefore I extended the DeckWorkspace, so that the the controls are only redrawed when they are initialized. This can be done through the WM_SETREDRAW message. Note that this technique can also be used for other workspaces. public class DeckWorkspaceEx: DeckWorkspace
{
int freezePainting = 0;
const int WM_SETREDRAW = 0xB;
[DllImport("User32")]
static extern bool SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);
protected void FreezePaintingOn()
{
if (IsHandleCreated && this.Visible)
{
if (0 == freezePainting++)
{
SendMessage(Handle, WM_SETREDRAW, 0, 0);
}
}
}
protected void FreezePaintingOff()
{
if (freezePainting != 0)
{
if (0 == --freezePainting)
{
SendMessage(Handle, WM_SETREDRAW, 1, 0);
Invalidate(true);
}
}
}
protected override void OnActivate(Control smartPart)
{
FreezePaintingOn();
try
{
base.OnActivate(smartPart);
}
finally
{
FreezePaintingOff();
}
}
protected override void OnClose(Control smartPart)
{
FreezePaintingOn();
try
{
base.OnClose(smartPart);
}
finally
{
FreezePaintingOff();
}
}
protected override void OnHide(Control smartPart)
{
FreezePaintingOn();
try
{
base.OnHide(smartPart);
}
finally
{
FreezePaintingOff();
}
}
protected override void OnShow(Control smartPart, SmartPartInfo smartPartInfo)
{
FreezePaintingOn();
try
{
base.OnShow(smartPart, smartPartInfo);
}
finally
{
FreezePaintingOff();
}
}
}
Building an application and/or library usually starts with an OO design. Typically from that design you will define interfaces and implement base classes, which can be used as a starting point for building your application. Defining the signature of a base class is very important. More specific, the visibility (public, protected & private) and purpose (virtual or not) of the methods are very important. Take for example an order-entry form based application that contains several screens for adding and updating data. Every screen will need to implement a kind of save method for persisting the changes. The very basic structure of your design can be: public interface IDataView
{
void Save()
}
public class DataViewBase: IDataView
{
public virtual void Save()
{
}
}
Here the intention is that for example every screen of your application need to inherit from DataViewBase and implement the Save method. The problem with this design, is that the interface is marked as virtual (see Virtuality) and is responsible for two jobs, namely that it is part of an interface and for specifying the implementation.
A better way is to apply the Template Method design pattern, also called the 'Hollywood principle', that is, 'Don't call us, we'll call you'. (This pattern is also used a lot throughout the .NET SDK library.) public class DataViewBase: IDataView
{
public void Save()
{
DoSave();
}
protected virtual void DoSave()
{
}
}
This way you have complete control of the interface and you can easily add some logging before and after the save for example, extra checks, etc. If for example you need to implement whether a form-screen is dirty or not, you can easily plug it in as follow: public class DataViewBase: IDataView
{
public void Save()
{
// do some checks
// do some logging
if (IsDirty())
DoSave();
}
protected virtual void DoSave()
{
}
protected virtual bool IsDirty()
{
return true;
}
}
If for example you need to extend the application such that when the screen is dirty you get a dialog box asking if you want to save or not. You can simply change the Save method without affecting the derived classes public class DataViewBase: IDataView
{
public void Save()
{
// do some checks
// do some logging
if (IsDirty())
if (MessageBox.Show("Do you want to save?", "Information",
MessageBoxButtons.YesNo,
MessageBoxIcon.Question) == DialogResult.Yes)
DoSave();
}
protected virtual void DoSave()
{
}
protected virtual bool IsDirty()
{
return true;
}
}
Due to the fact that the interface and the custom implementation is separated, we can easily extend and have control of the interface. In the other case we would have a lot of code duplication and in most cases we would violate the Liskov Substitution principle.
Here I describe how you can add syntax highlighting (C#, SQL, Javascript, etc.) in MediaWiki. In MediaWiki you can add syntax highlighting through GeSHiHighlight but I found it interesting for combining the world of PHP and .NET. For syntax highlighting in .NET I used the CodeHighlighter ASP.NET Control from Actipro Software.
The intersection between PHP and .NET for communication are web services. Therefore I created a .NET webservice that provides the method Parse with the parameters code and languagekey (= C#, SQL, XMl, etc.) which returns a HTML string.
using System;
using System.Web;
using System.Web.Services;
using System.Text;
using System.Web.Services.Protocols;
using System.Configuration;
using ActiproSoftware.CodeHighlighter;
using ActiproSoftware.SyntaxEditor;
[WebService(Namespace = "http://tempuri.org/SyntaxHighlighting")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class SyntaxHighlighting : System.Web.Services.WebService
{
[WebMethod]
public string Parse(string code, string languageKey)
{
if (string.IsNullOrEmpty(code))
return string.Empty;
SyntaxLanguage language = GetSyntaxLanguage(languageKey);
if (language == null)
throw new ApplicationException("LANGKEYNOTEXIST");
CodeHighlighterEngine engine = new CodeHighlighterEngine();
engine.OutliningEnabled = false;
return engine.GenerateHtmlInline(string.Empty, code, language);
}
CodeHighlighterConfiguration GetCodeHighlighterConfig()
{
CodeHighlighterConfiguration config = (CodeHighlighterConfiguration)HttpContext.Current.Cache["CodeHighlighterConfig"];
if (config == null)
{
config = (CodeHighlighterConfiguration)ConfigurationManager.GetSection("codeHighlighter");
HttpContext.Current.Cache.Insert("CodeHighlighterConfig", config);
}
return config;
}
SyntaxLanguage GetSyntaxLanguage(string languageKey)
{
if (string.IsNullOrEmpty(languageKey))
return null;
CodeHighlighterConfiguration config = GetCodeHighlighterConfig();
foreach (string key in config.LanguageConfigs.Keys)
if (key.ToLower() == languageKey.ToLower())
return CodeHighlighter.GetLanguage(config, key);
return null;
}
}
In MediaWiki you can extend WikiText so that for example your xml tag is recognized by the parser. This way you can extend the HTML output. In this example you would write in WikiText the following statements:
<code language="C#">
public int x = 5;
</code>
In the extensions folder of MediaWiki you add a file called CodeHighlighting.php with the following content:
<?php
$wgExtensionFunctions[] = "wfCodeHighlightingExtension";
function wfCodeHighlightingExtension()
{
global $wgParser;
$wgParser->setHook('code', 'renderCode');
}
function renderCode( $input="", $argv=array() )
{
$result = SyntaxHighlighting($input, $argv['language']);
return '<pre>' . trim($result) . '</pre>';
}
function SyntaxHighlighting($code, $languageKey)
{
$location = 'http://localhost/SyntaxHighlightingWS/SyntaxHighlighting.asmx?wsdl';
$result = $code;
try
{
$client = new SoapClient($location);
$arr = array("code" => $code, "languageKey" => $languageKey);
$result = $client->Parse($arr)->ParseResult;
}
catch(SoapFault $exception)
{
if (strpos($exception->faultstring, "LANGKEYNOTEXIST") === false)
{
throw $exception;
}
}
return $result;
}
?>
Through the setHook method you can extend WikiText. Here the method renderCode is called when a XML element named 'code' is inside your WikiText. Calling a web service in PHP 5 is easy with the SoapClient object. If the language we pass does not exist, we simply return the original string.
One more thing must be done, is to add an include in the LocalSettings.php in your MediaWiki folder.
include("extensions/CodeHighlighting.php");
Finally:

Microsoft announces on the msdn site that service pack 1 for Visual Studio 2005 will appear around Q3 of 2006.
I followed the Office 12 Ascend training in Paris that was teached by Patrick. The training was very successful and Patrick showed a lot of interesting stuff and demo's about Office and Sharepoint. So little time, and so much to play with, but thankfully there are the O12 labs which are very useful and detailed. On Patrick's blog you find a group photo with the team of Paris. Here are some pictures I took during the ascend training.
Nowadays, is every kind of enterprise application more complex because there is the need to have much richer UI experience, integration with other systems, security, etc. Therefore it's important to have a good architecture and design of your application, so that you can better maintain and extend your application. In every enterprise application you have a dependency to data resources. These resources can be to a database, web service, registry, file system, etc. It's a good practice to encapsulate all these dependent resources into services, such that the consumer (caller of the service) doesn't need to know the implementation details and the origin of the data. That pattern is used a lot and is called a Service Gateway or Service Agent. There is a discussion on the difference between a Service Gateway that can be seen as consumer of a service and a Service Agent as a provider, but in the community both terms are used and mixed. The dependency between the consumer and the service is a contract which is typically a set of interfaces and business entities. In most cases, the service interface acts as a facade pattern, it encapsulates all subsystems underneath.  A typical example of a service agent is: public interface ICustomerAgent
{
Customer GetCustomer(int customerId);
Order[] GetOrders(int customerId);
}
Note that the interface doesn't expose any details about the underlying system (e.g. database, xml, etc.) and communication protocol (e.g. web service, remoting, etc.).
Porgramming the UI of an application is typically the most difficult part and a challenge to achieve encapsulation and loose coupling. Thankfully there is for .NET 2.0 the Composite UI and the Smart Client Baseline Architecture Toolkit which guides you to an architecture for developing smart clients. Offcourse there is still the bible that every developer should read/know, it's the GoF book that describes a set of design patterns.
One of the drawbacks of a designer like in Visual Studio.NET, is that it is so easy to drag and drop (in dutch I call it 'drag en drol') components, change some attributes and going through wizards for making your application. For prototyping and demo's this is good enough, but for real enterprise applications it's not. If you want you can write an application that has only one class (= form), named Form1.cs that includes all UI logic, business logic, data access, security, etc but that's not what we want.
Building the UI is basically populating UI controls with data that resides in business entities. This means that for example an array of customers that must be shown in a list, means that every customer entity must be translated to a ListViewItem (if we don't use databinding). In most of the cases this logic resides in the form/usercontrol itself, but in fact it can be seen as a separated responsability for mapping a customer entity to a ListViewItem and vice versa (like in SC-BAT). This means that we can have something like: public static class CustomerMapper
{
public static ListViewItem ToListViewItem(Customer customer) { ... }
public static Customer FromListViewItem(ListViewItem listViewItem) { ... }
}
And in your form/usercontrol you write: foreach (Customer customer in customers)
customerListView.Items.Add(CustomerMapper.ToListViewItem(customer));
In every project there are some OO concepts and patterns I always try to achieve maintainability and extensibility. Making good OO designs is in my opinion a matter of experience, creativity and making abstractions. My conclusion...
The art of OO programming is to define the set of responsabilities (= objects), to encapsulate and to interact them in a loosely coupled way.
The patterns & practices team introduces a new project, called Baseline Architecture Toolkit (BAT). It's a collection of carefully selected, designed, and integrated guidance assets which include: - Reference Implementations
- Application Blocks (such as CAB and EntLib)
- Hands-On-Labs
- How-Tos
- Guidance Automation Packages automating common tasks
- Documentation bringing all the parts together and describing the rationale behind the key smart client design recommendations.
The toolkit provides an effective way for architects, dev leads and developers to create high-quality baselines for their smart client applications, addressing non-trivial design and development challenges. The toolkit will provide reusable assets, guidance and examples for solving those challenges in the most common scenarios. Also, the guidance will be open and customizable, so you will be able to adjust it to your specific needs. There is a Smart Client Baseline Architecture Toolkit released on GotDotNet and it will be updated every 3-4 weeks and is based on the CAB. On Channel 9 you can find 2 casts about Smart Client BAT:
Here are some interesting blogs that are dedicated to Virtual PC There are some fundamental features in Virtual PC that you really have to look at. For example differencing disks, see HOWTO: Use Virtual PC's Differencing Disks to your Advantage and you can also compress your VHD files, see Compact Your VHD Files. Tip On several keyboard layouts and for example on a AZERTY belgian keyboard you need the [Alt Gr] key for the backslash, square brackets, etc. Inside Virtual PC the [Alt Gr] key doesn't work, therefore you can use an alternative for the [Alt Gr] key, which is [Ctrl] + [Alt]. Update: There is a hotfix now for the ALTGR problem.
The Windows SDK - Janary 2006 CTP is available for download and can be used for developing WinFX applications (WWF, WPF & WCF). This page give you the several components that are needed for developing WinFX applications, these are:
When I tried to install the SDK, I received the message that the user has cancelled the installation. In the config file I had the following statements:
0:03:18 vrijdag 20 januari 2006: [SDKSetup:Error] Config_Products_Configure: Configuration of Product Microsoft .NET Compact Framework 2.0 (failed): User cancelled installation. 0:03:18 vrijdag 20 januari 2006: [SDKSetup:Info] Config_Products_Configure: End configuration of product: Microsoft .NET Compact Framework 2.0 0:03:18 vrijdag 20 januari 2006: [SDKSetup:Info] Config_Products_Install: End installation of product: Microsoft .NET Compact Framework 2.0 0:03:18 vrijdag 20 januari 2006: [SDKSetup:Error] Config_Products_Install: Windows SDK Setup (failed): Installation of the "Microsoft .NET Compact Framework 2.0" product has reported the following error: User cancelled installation.
The solution was to simply remove the Microsoft .NET Compact Framework 2.0 from the Add/Remove Programs in the control panel. After that the installation was successfull.
Some years ago on a project I needed a usercontrol for code coloring SQL statements. At that time I reused a dll library that is used inside the query analyzer of SQL server. I wrote a little article about that topic, I think it gives some useful information about COM interop in .NET.
Today I released an add-in for Visual Studio .NET 2005 that allows you to drag components onto the designer surface. It's called ComponentDropper and you can even watch a movie to know what it does and how to use it.  A very good tool for screen capturing is Windows Media Encoder. It's from Microsoft and you can download it, if you have a legal version of Windows XP. Windows Media Encoder 9 Series is a powerful tool for content producers who want to capture audio and video content using the many innovations in Windows Media 9 Series including high-quality multichannel sound, high-definition video quality, support for mixed-mode voice and music content, and more.
On my current project we are developing a windows forms application in Visual Studio 2005. We are still using CruiseControl.NET for continuous integration and unit testing, because setting up a team foundation server would give an overhead right now. For unit testing we like to have the nice debug and built-in features of MSUnit and the unit tests automatically tested by CruiseControl.NET through NUnit. The good thing about the two libraries, is that they work through attributes and the common Assert methods are the same. The template we use for our unit tests, looks like: #if NUnit
using NUnit.Framework;
#else
using Microsoft.VisualStudio.QualityTools.UnitTesting.Framework;
#endif
namespace MyUnitTests
{
[NUnit.Framework.TestFixture]
[Microsoft.VisualStudio.QualityTools.UnitTesting.Framework.TestClass]
public class MyTestClass
{
[NUnit.Framework.Test]
[Microsoft.VisualStudio.QualityTools.UnitTesting.Framework.TestMethod]
public void MyTestMethod()
{
}
}
}
We migrated our project to the new Composite UI. Yes, today a new release of the cab has been released. In the unit tests of CAB I noticed they did the same trick, but with aliases: #if !NUNIT
using Microsoft.VisualStudio.TestTools.UnitTesting;
#else
using NUnit.Framework;
using TestClass = NUnit.Framework.TestFixtureAttribute;
using TestMethod = NUnit.Framework.TestAttribute;
using TestInitialize = NUnit.Framework.SetUpAttribute;
using TestCleanup = NUnit.Framework.TearDownAttribute;
#endif
namespace MyUnitTests
{
[TestClass]
public class MyTestClass
{
[TestMethod]
public void MyTestMethod()
{
}
}
}
Today I published the new IStaySharp.NET. It's rewritten in ASP.NET 2.0 and hosted by WebHost4Life. I also added a new FAQ entry about coverting FILETIME and DateTime, you will encounter FILETIME when you are using COM interop. There is a lot of coming during the next months. So stay tuned!
I updated the IStaySharp.WebBrowser control with some bug fixes. - DocumentText fix in IEBrowser
- Fix of member TranslateAccelerator in IDocHostUIHandler
- ScrollBarsEnabled fix in IEBrowserSiteBase
More information can be found on IStaySharp.
In .NET 2.0 you will notice that every data has among others an extra method called TryParse. TryParse and Parse are semantically the same but differ in the way they handle errors. Parse method will throw an exception if it cannot convert the string, whereas the TryParse method returns a boolean to denote whether the conversion has been successfull or not, and returns the converted value through an out parameter. int result = 0;
bool success = true;
string badValue = "12a45";
string goodValue = "1245";
try {
result = int.Parse(badValue);
}
catch {
success = false;
}
Debug.Assert(success == false);
Debug.Assert(result == 0);
success = true;
try {
result = int.Parse(goodValue);
}
catch {
success = false;
}
Debug.Assert(success == true);
Debug.Assert(result == 1245);
// int.TryParse
success = int.TryParse(badValue, out result);
Debug.Assert(success == false);
Debug.Assert(result == 0);
success = int.TryParse(goodValue, out result);
Debug.Assert(success == true);
Debug.Assert(result == 1245);
The reason why the TryMethod is introduced, is because exceptions are expensive. On http://www.codinghorror.com/blog/archives/000358.html you find a benchmark tool and you notice that the (default) Parse method is a lot slower.
One tip: For extensive use of string concatenation you use the StringBuilder class, for converting data types you apply the TryParse method.
The RealDN site, a blog site where employees of Real Software share their knowledge about technology, has been updated.
In .NET 1.1 you cannot assign the NULL value to a value type (e.g. int, float, etc.). There are some situations where this is needed, typically in database scenarios. In .NET 2.0 there is a new type called nullable. The nullable type implements the INullableValue interface and looks like: public interface INullableValue
{
bool HasValue { get; }
object Value { get; }
}
The idea is that a nullable type combines a value (Value) of the underlying type with a boolean (HasValue) null indicator. The underlying type of a nullable type must be a value type. Nullable<int> x = 9;
Debug.Assert(x.HasValue);
Debug.Assert(x == 9);
Debug.Assert(x.Value == 9);
Debug.Assert(x.GetValueOrDefault(5) == 9);
x = null;
Debug.Assert(x.HasValue == false);
Debug.Assert(x.GetValueOrDefault(5) == 5);
You can also use the ? type modifier to denote a nullable type. int? y = 9;
Debug.Assert(y.HasValue);
Debug.Assert(typeof(int?) == typeof(Nullable<int>));
In .NET 2.0 there is a new operator, called the null coalescing operator, ??. For example the statement x ?? y is x if x is not null, otherwise the result is y. Note that this operator also works with reference types. int? a = null;
int? b = 6;
Debug.Assert((a ?? b) == b);
a = 9;
Debug.Assert((a ?? b) == a);
b = null;
Debug.Assert((a ?? b) == a);
RemotingHelper is a little helper class by Ingo Rammer that enables you to use interfaces to access remote objects instead of the implementation. In .NET 2.0 there are a lot of new features, and one of them are generics. Especially with the RemotingHelper we deal with types and with the GetObject method we can use generics to parameterize the method by type. In .NET 1.1 we need to write something like ICustomerService customerService = RemotingHelper.GetObject(typeof(ICustomerService)) as ICustomerService;
when using generics in .NET 2.0 we can simply write ICustomerService customerService = RemotingHelper.GetObject<ICustomerService>();
No need to to cast and no typeof operator!
Below you find a version of the RemotingHelper using generics, or you can download the RemotingHelper.zip using System;
using System.Collections.Generic;
using System.Runtime.Remoting;
public class RemotingHelper
{
private static bool isInit;
private static IDictionary<Type, WellKnownClientTypeEntry> wellKnownTypes;
public static T GetObject<T>()
{
if (!isInit)
InitTypeCache();
WellKnownClientTypeEntry entry = wellKnownTypes[typeof(T)];
if (entry == null)
{
throw new RemotingException("Type not found!");
}
return (T)Activator.GetObject(entry.ObjectType, entry.ObjectUrl);
}
public static void InitTypeCache()
{
isInit = true;
wellKnownTypes = new Dictionary<Type, WellKnownClientTypeEntry>();
foreach (WellKnownClientTypeEntry entry in RemotingConfiguration.GetRegisteredWellKnownClientTypes())
{
if (entry.ObjectType == null)
{
throw new RemotingException("A configured type could not be found. Please check spelling");
}
wellKnownTypes.Add(entry.ObjectType, entry);
}
}
}
I updated my blog site to version 1.8 of DasBlog and created a new theme called 'Business'. I will release soon a version of the theme so that you can use it for your own blog site. Any feedback and suggestions are welcome!
I have missed that one, but Dasblog has released a new version. The new Dasblog 1.8 can be downloaded here. I think that I am going to upgrade now, i'm still running 1.5. Update: The upgrade went without any problems and the content can be converted with the DasBlogUpgrader.exe tool. As you can see there is a cool theme included named Portal from Johnny Hughes.
A new version of the Enterprise Library has been released. More information about the changes since the January release can be found here.
In the course of next week I will release a new version of IStaySharp.WebBrowser. It contains new features, fixes and the set of properties and methods are made compatible with the webbrowser control in VS.NET 2005 (e.g.: EnableBack, DocumentText, ObjectForScripting, etc.). New Features: - Implemented the Travel Log interface
- Easy communication between Javascript and .NET through the 'ObjectForScripting' property
- NUnit tests
- Improved model for extending the Site (IOleClientSite) of the webbrowser.
- Fixes and improved functionality for Mozilla
- Printer service for modifying header, footer and margins
I've added a FAQ entry named 'How to send data between forms' to IStaySharp that shows you how to send data with the COPYDATASTRUCT and SENDMESSAGE function.
I bought the domain name a couple of months ago but finally the site is online. The purpose of IStaySharp.NET is to provide a resource site for .NET developers (articles, faq, etc.) and to provide information on the projects I am working on. The two projects currently online is log4xsl which is a xsl for viewing XML files generated by log4net. Below you find an example of the output:  The WebBrowser library is the second project and fully embeds the webbrowser functionality of Internet Explorer and Mozilla. It also provides some extra functionality for Internet Explorer. Below you find a sampe project (top is IE and bottom is Mozilla) that can be downloaded on the site.  There are other projects coming and will be updated to the site. If you have any questions and/or feedback please contact me (contact mail can be found in the About menu).
It has been a long time ago, but log4net has released a new version. The release notes can be found here
If it depends on Shawn Burke (Developer Division Program Manager) it must be possible to ship the Windows Forms source code and PDBs in version .NET 2.0. More information about that great idea can be found on the blog
From Patterns and Practices we can expect soon an Enterprise Library. This is a single application block that will integrate the most used application blocks. For the first release it will include: - Data Access
- Exception Handling
- Caching
- Configuration
- Logging
- Security
- Cryptography
I am convinced that the Enterprise Library will be the defacto standard application block for each application/project. All the functionalities are so fundamental that you can't without it. Like the site mentions, it enforces Consistency, Extensibility, Ease of Use and Integration. The GodDotNet workspace for Enterprise Library can be found here.
FlexWiki is now the third application that Microsoft releases under an open-source licence. The first application was Windows Installer XML (WiX) and the second the Template Library (WTL). The source for FlexWiki can be found here.
I am currently working on a project where we have to interact several applications (COM, .NET, Linux, Java, etc.) together through a messaging system. One of the applications is a windows application that exposes an application object. In this way we can host it through .NET. The problem is that the application object doesn't expose any events; no exit, close or quit event. What I need to properly close the .NET host.
In contrast to the Win32 SendMessage you can use system hooks to listen to events from any application. But after googling I noticed that .NET doesn't support global hooks! The only way to accomplish, is to make an unmanaged C++ DLL that catches the system hooks, and the .NET DLL will receive them. An example of that can be found on CodeProject Global System Hooks in .NET. Unfortanetly it only receives mouse and keyboard events, so I have to extend it to receive application events.
I think one of the most popular code snippet tools is Code Library for .NET. I don't know how it's with the current version, but all previous versions I tested were very unstable. But it really has all the features I need for a code snippet tool.
I found some other code snippet tools named CodeKeeper.NET and SnippetBox.NET. It's surprising that the two sites are very similar, just search/replace of some text . Unfortunately it's not for free.
I wonder what you guys use as code snippet tool...
Marc Clifton added a nice introduction to declarative versus imperative programming.
Imperative programming (source) Describes computation in terms of a program state and statements that change the program state.
Declarative programming (source) Gives the computer a list of instructions to execute in a particular order, declarative programming describes to the computer a set of conditions and lets the computer figure out how to satisfy them
Like Marc Clifton describes in the article, we are already using declarative techniques like resource files, config files, etc. Many libraries like FABRIQ, User Interface Process Application Block for .NET, log4net, etc. uses a XML file to describe a sort of workflow in a declarative way.
Therefore I try to use it where possible on every project. Certainly when it comes to making forms. I just hate the generated code inside the InitializeComponent of a form/control, it is more elegant, readable and maintainable by describing it in a declarative way. For example a menubar would look like this:
<MENUBARITEM Text="Edit"> <MENUITEMS> <MENUBUTTONITEM Text="Cut" /> <MENUBUTTONITEM Text="Copy" /> <MENUBUTTONITEM Text="Paste" /> ...
instead of a bunch of statements that are needed for declaration, initialisation, setting properties and to composite the controls together. In this way it is also very hard to see the relationships between the objects!
I've seen on MSDN that the WebBrowser control has a new event in SP2, named NewWindow3 . It's an extension to the NewWindow2 event with additional info in the eventargs. The url that initiates the new window, and the url where the new window is redirecting to. I am pretty sure that this has something to do with the new popup blocker that will be added in Windows XP SP2 :) 
I found somewhere in the newsgroups a nice trick for creating typed collections. In most of the cases typed collections only differ in the type they get and set. To make things easier we can do the following. Create an integer collection class, like below: using System;
using System.Collections;
using ItemType = System.Int32;
public class IntCollection : CollectionBase
{
public void Add(ItemType val)
{
this.List.Add(val);
}
public void Remove(ItemType val)
{
this.List.Remove(val);
}
public ItemType this[int index]
{
get { return (ItemType)this.List[index]; }
set { this.List[index] = value; }
}
}
Here we use an alias named ItemType that denote the type that the collection must work with. If we want a collection of the class Employee, we simply copy/paste the IntCollection class and change the class name to EmployeeCollection and set the ItemType to Entities.Employee for example. So we have something like:
using System;
using System.Collections;
using ItemType = Entities.Employee;
public class EmployeeCollection: CollectionBase
{
public void Add(ItemType val)
{
this.List.Add(val);
}
public void Remove(ItemType val)
{
this.List.Remove(val);
}
public ItemType this[int index]
{
get { return (ItemType)this.List[index]; }
set { this.List[index] = value; }
}
}
Offcourse you can use search and replace, but I found this method more elegant 
The last couple of weeks I concentrated on writing SharpBrowser. It was already subscribed for a long time on Sourceforge.net, but now I finally released an initial version . The main features of the initial version, is that it is tab-based and it can be used with IE or Mozilla! SharpBrowser uses the great UI library from divil.co.uk for the menus, toolbars, docking and documents. One of the features is that you for example can choose the UI rendering, e.g.: Office2003, Everett and Whidbey. In order to use Mozilla you just have to download the Mozilla 1.7 ActiveX Control and install it. If the installation is successful you will see an extra menuitem, where you can choose the browser: (left is IE, right is Mozilla) Note that this is an initial release, and that there a bunch of features that must be implemented. In the following weeks I will concentrate on implementing features that are included in the standard IE and after that extra features like: - cookie mamagement
- download management
- popup killer
- google toolbar
- view partial source
- event viewer
- manage broken links
- mouse gestures
- plugin-mechanism
- etc.
That's why I started writing SharpBrowser, because I am convinced that you can implement a set of very usefull features for a browser that are not (yet) included in IE. I am also thinking about features for web developers, like a viewstate decoder, better support for debugging javascript, test scenarios, etc. This project give me also the opportunity to experiment with libraries like MyXaml, log4net, Microsoft Application Blocks, etc. For me it is important that I can learn of it, and that the project uses the right concepts, design patterns, libraries, etc. That's the reason why I distribute it in open-source so that we can share our knowledge! In the next couple of days I will explain some concepts that I implemented for SharpBrowser. Patterns like the visitor, command, composite, facade, etc. If you have any suggestions, ideas for new features, or want to share about good practices, design patterns, libraries, please let me know! You can send an email to me@delarou.name SharpBrowser v0.5 (1,79 MB) (source code will be available in a couple of days)
In order to have XP visual styles inside Visual Studio.NET you can simply add a manifest file to devenv.exe. Simply download the file manifest.zip and extract it into the directory where devenv.exe resides. For Visual.Studio.NET 2003 it's: C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE
This will ensure that your forms designer uses the XP visual style (only if the FlatStyle of a control is set to System) and even custom-made addins are in XP style!
RazorToolbox is a set of utilities/tools in the form of addins, macros, components, etc. for Visual Studio.NET. In the initial release of RazorToolbox we have ComponentDropper. In .NET you can easily build components (= also controls), but in order to use them on your designer surface you have to add them in the toolbox of Visual Studio.NET. But there are some problems. For example if you are writing an exe-application and added some components in the exe-project, you cannot add them to the toolbox, because the toolbox only accepts DLLs. Another issue is when you are developing a set of components in a control library, you will have to refresh the toolbox for each component you added in the library, it is not automatically refreshed and is time-consuming. Besides that there are some controls in .NET that are not displayed in the toolbox, for example the PropertyGrid. ComponentDropper allows you to drop a component on the designer surface from a set of assemblies. For example if you are writing an exe-application and added a usercontrol named UserControl1 like the screennshot below: 
Take the ComponentDropper from the toolbox and drag it over the form where you want to drop UserControl1. You get something like:  This list gives the set of components that reside in the current project and the assemblies that are referenced in the project. There you can double-click on UserControl1 and it's added to the form. There are some settings, like you can first build the project before ComponentDropper search for components in the current project. Also you can indicate that ComponentDropper searches in the list of references in the current project. A list of references can be excluded through expressions, for example: System.*.  Download:RazorToolbox.zip (223,59 KB) Any feedback and comments are greatly appreciated!
Now you don't need anymore the architect edition of Visio to generate your UML diagrams from an assembly. Now you can use Assembly2Visio from GotDotNet.
It has the extra feature that you can use regular expressions to filter class names and its totally integrated in Visio 2003 through a macro. Nice tool!
Today I published the first version of the library delarou.Browser. The aim of the library is to wrap the browser functionality of Internet Explorer and Mozilla. It acts like a normal windows control in your toolbox and you can easily drag and drop the controls IEBrowser and/or MozillaBrowser on your designer surface. More information about the library can be found here. Below you find a screenshot of the demo application (top MSIE, bottom Mozilla):  This library is an initial version and will frequently be updated, because this is a part of a bigger project that I am working on, namely SharpBrowser (more details about that project will come soon). Note that the control IEBrowserHost is not yet intended for use, it’s still in development
In a distributed application I created a project (facade) where all business logic reside. I wrote a ConfigSettings class where all configuration settings reside, like for example the connectionstring. These settings are fetched from an XML file through the XMLSerializer from .NET. To enforce layer abstraction I changed the protection level of the ConfigSettings class to internal. But when I try to deserialize the xml I get an InvalidOperationException! I was a little bit surprised that apparently the XMLSerializer can only (de)serialize public classes!!! After changing the protection level to public everything works fine, but there goes my abstraction (of course you can write your own implementation) some changes
Today you see a lot of XAML-like implementations for .NET framework 1.1. XAML (pronounced "Zamel") is part of AVALON in Longhorn and it allows you to describe the layout of applications. Basically, you describe via XAML-tags your controls, events, etc. it's very intuitive.
One of the projects is wfml. You can find the article with the source code here.
Another project which is still in beta is xamlon. Closer to the release date Xamlon will be licensed per developer.
An implementation under the BSD License is MyXaml and it is increasingly successful. I think I will first play around with this implementation . An article from the author of MyXaml can be found on CodeProject
I think the developers who first implemented the concept were ic#code. They setup a library XmlForms which can be downloaded here and is used in SharpDevelop.
The ASP.NET Resource Kit is a nice bundle of tutorials, tools and free controls for any developer starting ASP.NET. It can be downloaded here (about 134MB). Go and get it!
|