Wednesday, 26 November 2008
Microsoft® Visual Studio Team System 2008 Database Edition now supports SQL Server 2008
http://www.microsoft.com/downloads/details.aspx?familyid=bb3ad767-5f69-4db9-b1c9-8f55759846ed&displaylang=en
Remember, "Datadude" is free for people with a license for Microsoft® Visual Studio Team System 2008 Developer Edition:
http://callumhibbert.blogspot.com/2008/10/visual-studio-team-system-developer.html
Tuesday, 25 November 2008
Windows Server 2008 Core will support managed code
Seems like Microsoft have changed their mind and the Core install will support ASP.NET and a "subset" of .NET 2.0, 30 and 3.5 when SP2 arrives.
Thursday, 6 November 2008
DebugView and Windows Server 2008
One added bonus is that calls to System.Diagnostics.Debug.WriteLine() are not included in the Release build of your assemblies so you're not peppering your code with statements you don't want running in production.
I've used this tool for a long time but I've discovered on Windows Server 2008 you need to run it with Elevated Privileges to be able to capture events from the Kernel and Win32. You need these enabled (under the "Capture" menu) so catch messages from applications hosted in IIS etc.
Tuesday, 28 October 2008
Using a custom dictionary for FxCop in Visual Studio 2008
The post is here: http://duncanjasmith.blogspot.com/2008/07/creating-custom-dictionary-for-code.html
The short story is that in VS2008 there is a "BuildAction" of "CodeAnalysisDictionary" that you can apply to Project Items. Copy and edit the built-in Custom Dictionary from "%systemdrive%\Program Files\Microsoft Visual Studio 9.0\Team Tools\Static Analysis Tools\FxCop\CustomDictionary.xml" and away you go. Read his post for details on how to have an FxCop Custom Dictionary applied Solution wide.
Professional Developer Conference 2008 - Day One Summary
Key Note - Azure Services Platform
During the key note, Ray Ozzie announced Microsoft's Azure Services Platform (code name "Red Dog"). This is a "services platform" for the cloud. This platform has been used to build Live Services and will be the building blocks for .NET Services, SQL Services, SharePoint Services and Dynamics CRM Services.Service Level Agreements (with financial guarantees) are scheduled for 2009. It should be noted that it's unlikely there will be an explicit Version 1 - these services will constantly evolve.
Details and analysis here:
- http://www.microsoft.com/azurehttp://www.microsoft.com/presspass/press/2008/oct08/10-27PDCDay1PR.mspx
- http://www.liveside.net/main/archive/2008/10/27/live-mesh-how-does-live-mesh-relate-to-azure.aspx
- http://www.theregister.co.uk/2008/10/27/microsoft_amazon/http://weblogs.asp.net/pgielens/archive/2008/10/27/a-lap-around-windows-azure.aspx
Visual Studio 2010 and .NET Framework 4.0 CTP
The PDC kicked off with Microsoft releasing a CTP of Visual Studio 2010 and .NET Framework 4.0. Please note this does not include any Oslo features, Oslo integration with Visual Studio will come in a later CTP.
Details here:
- http://www.microsoft.com/downloads/details.aspx?FamilyID=922b4655-93d0-4476-bda4-94cf5f8d4814&DisplayLang=en#filelist
Silverlight 2.0
Microsoft released Silverlight 2.0 for Windows and Mac. This is an important release as it includes a cross platform implementation of the .NET Framework. The original moniker for this project was WPF/E "Windows Presentation Foundation Everywhere" and was originally announced by Jim Allchin at the last PDC in 2005.
Details here:
http://www.theregister.co.uk/2008/10/27/silverlight_two_review/
Microsoft Federation Gateway
The Microsoft Federation Gateway is an identity hub that brokers identities across disparate applications and services. For seamless integration with Active Directory, Microsoft has released a server component called the Microsoft Services Connector. It should be noted that this is implemented using open standards. This appears to be an implementation of Microsoft Active Directory Federation Services (ADFS).
Details here:
http://dev.live.com/blogs/devlive/archive/2008/10/27/420.aspx
Windows Live & OpenID
Windows Live publicly committed support for the OpenID platform enabling users to use their Windows Live ID to sign into any OpenID site.
Details here:
http://dev.live.com/blogs/devlive/archive/2008/10/27/421.aspx
More information on OpenID here:
Oslo Developer Centre
Microsoft announced the Oslo Developer Centre. You can download an Oslo CTP now from this site. This CTP includes documents and tools for working with the “M” language.
Main site:
http://msdn.microsoft.com/en-gb/oslo/default.aspx
Oslo SDK direct link:
http://download.microsoft.com/download/4/2/3/423FFDF3-B0B9-4EF0-990F-82DDE530B672/RepositoryOct2008CTP.msi
WCF REST Starter Kit
This is a preview of the REST features for WCF 4.0. Find it at the WCF Developer Centre.
Main site:
http://msdn.microsoft.com/wcf/rest
WCF REST Starter Kit direct link:
http://www.codeplex.com/aspnet/Wiki/View.aspx?title=WCF%20REST
Day One Summaries and Digests
S. Somasegar, Senior Vice Preseident of the Developer Division sums things up here:
http://blogs.msdn.com/somasegar/archive/2008/10/27/announcements-from-pdc-2008.aspx
Steve Martin, Director of Product Management for Microsoft's Connected Systems Division talks about where the Azure Services Platform is going and what is available now:
http://blogs.msdn.com/stevemar/archive/2008/10/27/pdc-day-1-azure-services-platform-ctp-availability-and-much-more.aspx
Matt Milner from Pluralsight talks about the Azure Services Platform in more depth:
http://www.pluralsight.com/community/blogs/matt/archive/2008/10/27/pdc-keynote-day-1.aspx
Friday, 17 October 2008
Windows Server 2008 as a workstation (Part 3)
One way around this is to download Windows Live Messenger Version 8.1 from Microsoft.com. You can find it here: http://www.microsoft.com/downloads/details.aspx?familyid=d78f2ff1-79ea-4066-8ba0-ddbed94864fc&displaylang=en
This works fine for Windows Server 2008.
Windows Server 2008 as a workstation (Part 2)
As per Windows 2003 Server, the operating system employs the "Internet Explorer Enhanced Security Configuration" component to lock down IE. This makes total sense when Windows Server 2008 is being used as a server but when using it for general use its not user friendly.
In Windows 2003 Server you were able to completely un-install the "Internet Explorer Enhanced Security Configuration" component from Add/Remove Programs in Control Panel. That is not possible in Windows Server 2008 as the component is baked into the OS. You can't remove it but you can disable it.
To do this open Server Manager (Start --> Administrative Tools --> Server Manager). On the right hand side under the "Security" section, click on "Configure IE ESC". This opens a new dialog box where you can disable Internet Explorer Enhanced Security Configuration for Admins and/or Users.
Thursday, 16 October 2008
Windows Server 2008 as a workstation
The first is that by default, the use of MSIs is prohibited (okay, this is more than a niggle). To be able to install additional programs you need to change the Local Group Policy. To do this run "gpedit.msc" and navigate to "Computer Configuration\Administrative Temaplates\Windows Components\Windows Installer". Change the "Disable Windows Installer" state to "Enabled".
The second issue is the annoying "Shut Down Windows" dialog that appears everytime you want to shutdown your box. This dialog box requires that you enter a reason everytime you shutdown or restart your box. I have found multiple articles and blogs that suggest you need to change the Local Group Policy. Done by running "gpedit.msc" again, navigating to "Computer Configuration\Administrative Temaplates\System" and changing the "Display Shutdown Event Tracker" state to "Disabled". But this does not appear to work, at least it didn't for me. What did work was editing a registry value. Open regedit.exe and go to "HKLM\SOFTWARE\Policies\Microsoft\WindowsNT". Create a new Key called "Reliability" and add a DWORD value at that location. The name should be "ShutdownReasonOn" and the value should be "0".
Repairing the .NET Framework 2.0 and 3.0 on Windows Vista and Windows Server 2008
The problem is that under Windows Vista and Windows Server 2008 these components are part of the operating system so you can't do a repair with the MSI like you normally can with installed programs. After doing some digging I found the answer here:
http://blogs.msdn.com/astebner/archive/2007/03/26/how-to-repair-the-net-framework-2-0-and-3-0-on-windows-vista.aspx
The short story is to run "sfc /scannow" with elevated privileges.
Sunday, 5 October 2008
Visual Studio Team System Developer & Database Editions are merged
Essentially MSDN Subscribers with a "Visual Studio Team System Developer" or "Visual Studio Team System Database" (or relevant Partner Programs) will be given access to the alternative SKU. Please note that these products are not a single installation, you need to install both products. This results in you having both SKUs installed which means you will get additional features/menus in Visual Studio. This affects the current toolset in addition to Rosario (VS2010).
This is a great move by Microsoft, the features of the Database Edition are incredibly useful to a developer. There is a new Database Project type that supports MSBuild, this means you can build/rebuild you database schema from the IDE or from the command line. The schema compare facilities give you functionality broadly equivalent to RedGate's fantastic SQL Compare product (http://www.red-gate.com/products/SQL_Compare/index.htm).
Monday, 30 June 2008
XBAP applications and Strong Naming.
When you Strong Name an assembly, by default the assembly will not allow Partially Trusted callers. As the sandbox in which your XBAP applications run is running with Partial Trust, this means that you will get the following error in the browser when you try to run your application
Startup URI: C:\dir\MyApplication.xbapApplication Identity: file:///C:/dir/MyApplication.xbap#MyApplication.xbap, Version=x.x.x.x, Culture=neutral, PublicKeyToken=0000000000000000, processorArchitecture=msil/MyApplication.exe, Version=x.x.x.x, Culture=neutral, PublicKeyToken=0000000000000000, processorArchitecture=msil, type=win32
System.Security.SecurityException: That assembly does not allow partially trusted callers. at System.Security.CodeAccessSecurityEngine.ThrowSecurityException(Assembly asm, PermissionSet granted, PermissionSet refused, RuntimeMethodHandle rmh, SecurityAction action, Object demand, IPermission permThatFailed) at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args) at System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args) at System.Runtime.Hosting.ManifestRunner.Run(Boolean checkAptModel) at System.Runtime.Hosting.ManifestRunner.ExecuteAsAssembly() at System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext, String[] activationCustomData) at System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext) at System.Windows.Interop.PresentationApplicationActivator.CreateInstance(ActivationContext actCtx) at System.Activator.CreateInstance(ActivationContext activationContext) at System.AppDomain.InternalRemotelySetupRemoteDomainHelper(Object[] args) at System.Threading.Thread.CompleteCrossContextCallback(InternalCrossContextDelegate ftnToCall, Object[] args) at System.AppDomain.nCreateInstance(String friendlyName, AppDomainSetup setup, Evidence providedSecurityInfo, Evidence creatorsSecurityInfo, IntPtr parentSecurityDescriptor) at System.Runtime.Hosting.ApplicationActivator.CreateInstanceHelper(AppDomainSetup adSetup) at System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext, String[] activationCustomData) at System.Windows.Interop.PresentationApplicationActivator.CreateInstance(ActivationContext actCtx) at System.Windows.Interop.ApplicationLauncherXappDebug.Initialize() at System.Windows.Interop.DocObjHost.MS.Internal.AppModel.IBrowserHostServices.Run(String path, String debugSecurityZoneURL, String viewerUri, String fragment, String applicationId, MimeType mime, Object streamContainer, Object ucomLoadIStream, String userAgentString, Boolean isDebugMode, String progressAssemblyName, String progressClassName, String errorAssemblyName, String errorClassName)The action that failed was:LinkDemandThe method that caused the failure was:Void Main()
To prevent this problem, you need to mark your XBAP assembly with the AllowPartiallyTrustedCallersAttribute, for example:
[assembly: AllowPartiallyTrustedCallers]
With this Attribute your XBAP application will now run.
Wednesday, 25 June 2008
Microsoft Dynamics CRM 4.0 install error "The instance name must be the same as computer name."
"The instance name must be the same as computer name."
To fix this problem you need to update the name of the machine in SQL Server by executing the following:
sp_dropserver 'OldMachineName'
GO
sp_addserver 'NewMachineName', local
GO
You will also need to restart the SQL Server service. Please note you can't use this command to change the instance suffixes. For example you can NOT change "serverA\SomeInstance" to "serverA\AnotherInstance", you may only change "serverA\SomeInstance" to "serverB\SomeInstance".
For more information see the following MSDN article: http://msdn.microsoft.com/en-us/library/ms143799.aspx
You may also need to update Reporting Services: http://msdn.microsoft.com/en-us/library/ms345235.aspx
This situation can easily arise if you have a virtual envrionment and are cloning machines.
Monday, 7 April 2008
Windows 2008 Server Core does not support managed code
The Windows 2008 Server Core SKU does not support any managed code, that means no .NET applications at all. Period.
More info in the "Server Core Installation Option of Windows Server 2008 Step-By-Step Guide" here: http://technet2.microsoft.com/windowsserver2008/en/library/47a23a74-e13c-46de-8d30-ad0afb1eaffc1033.mspx?mfr=true
Apple Safari for Windows
While I hate the fonts (no where near as good as Internet Explorers Clear Type goodness) the browser itself is blisteringly fast. I use Newsgator On-line as my RSS aggregator and under IE it runs fairly slow (there is alot of JavaScript). Under Safari it is incredibly fast.
The browser wars are here again.
Sunday, 6 April 2008
MSBuild, VS2008 and "Invalid search path"
CSC : error CS1668: Warning as Error: Invalid search path 'C:\Program Files\\Microsoft SDKs\Windows\v6.0A\lib' specified in 'LIB environment variable' -- 'The system cannot find the path specified. '
The reason for this is that the environment variables configured for this command console assume you have installed the C++ components with Visual Studio (which I did not install for the sakes of disk space).
The easiest way to solve this problem is to create the path. The "'C:\Program Files\\Microsoft SDKs\Windows\v6.0A\" path should already exist, so just create a "Lib" folder at that location.
Its a simple fix but working out why this was a problem was tricky, it niggled me why a fairly straight forward install of VS2008 would have a not insignificant problem.
Thursday, 13 March 2008
Generating a Schema for the BizTalk SQL Adapter
This process isn't as straight forward as it should be an its easy to end up with a Schema where the value returned from the Stored Procedure is represented by a "Success" Element of "anyType which is useless.
Firstly, you must have a Stored Procedure that that returns a result set using "FOR XML AUTO". Secondly, when you run through the wizard you must add "XMLDATA" to the end of the Stored Procedure (and remove it after you have generated the Schema). The XMLDATA clause causes SQL Server to return the Schema for the result set (as well as the result). So, when you go through the wizard you must have a stored procedure looking something like this:
SELECT ColumnA, ColumnB FROM MyTable FOR XML AUTO, XMLDATA
After you have generated your schema, remove the "XMLDATA" clause to leave:
SELECT ColumnA, ColumnB FROM MyTable FOR XML AUTO
When you run through the wizard, most of the values you need to enter are obvious but when you get to the "Schema Information" screen, you need to change the "Port Type" to "Send".
When you get to the "Statement Information" screen, you need to enter valid values into the "Value" column (click the Value cell twice to enter data). Then hit "Generate", then hit "Next".
The SQL Adapter Wizard does not seem to support "FOR XML EXPLICIT", you get an error that says "the required attribute 'name' is missing". However, I would guess that if you can generate the boiler plate Schema using "FOR XML AUTO," you should be able to change your Stored Procedure and then manually edit the Schema generated by the Wizard to match what your XML EXPLICIT format.
Wednesday, 5 March 2008
Microsoft SharedView Version 1.0 available
Download from here: http://www.connect.microsoft.com/content/content.aspx?ContentID=5306&SiteID=94
Monday, 3 March 2008
Gated Check-ins and Team Foundation Server
Someone mentioned the "private build" feature of TeamCity where by you ask the build server to do a build of what you currently have but without actually checking in your code to the source tree.
I pointed out that this feautre is also supported by Team Foundation Server through an open source framework exisits called Gauntlet (http://www.opengauntlet.org/). The elevator pitch from the Gauntlet web site is as follows:
"OpenGauntlet...mimics a fundamental feature of Microsoft's internal development system (codenamed Gauntlet), also known as "Gated Checkins". It avoids the problems associated with large development teams whereby a single developer will check in non-compiling code, which subsequently causes delays in the development life cycle as the team waits for the issues to be resolved. It can also be configured to disallow check ins if the proposed code changes break the unit tests. The central principle is that users are not allowed to check code directly into source control. Instead, they shelve their changes with a specific naming prefix when they are ready to check some changes in, and OpenGauntlet unshelves their changes into a temporary workspace, checks the changes compile and pass unit tests, and then checks the changes into source control under the requesting developer's username."
I've not taken the plunge with setting this up yet, I have an upgrade to TFS2008 to do first, but it looks like a must have. Here's to less "red" builds!
Monday, 25 February 2008
NServiceBus
I subscribed to Udi Dahan's blog recently (http://udidahan.weblogs.us/). I saw him present a session called "Designing High Performance, Persistent Domain Models" at Tech-Ed 2007 in Barcelona. It was one of the best sessions I saw during the week. How he got a talk with NHibernate demo material into Tech-Ed I'll never know.
I read through some of the old blog posts to catch up on what he'd been doing since Tech-Ed and I noticed he'd been working on a open source messaging framework called "NServiceBus" (http://www.nservicebus.com/).
This is interesting because I frequently encounter projects that require some kind of message bus with pub/sub features but don't want to take the plunge with BizTalk as its either too heavy weight or the license cost is prohibitive.
The project seems to be progressing, version 1.7 has been released at the time of writing and there is an active news group (http://tech.groups.yahoo.com/group/nservicebus/).
I will evaluate the framework at some point and report back.
Saturday, 23 February 2008
WCF Services and Dependency Injection with Castle
You might encounter a situation where you are leveraging the dependency injection design pattern in your application. At first this might seem problematic to implement if you are using WCF Services.
For example, you may have the following classes:
public interface ICustomerRepository { // Code } public class CustomerRepository : ICustomerRepository { // Code } [ServiceContract] public interface ICustomerService { [OperationContract] void AddCustomer(AddCustomerRequest addCustomerRequest); } public class CustomerService : ICustomerService { private readonly ICustomerRepository _customerRepository; public CustomerService(ICustomerRepository customerRepository) { _customerRepository = customerRepository; } /// <remarks /> public void AddCustomer(AddCustomerRequest addCustomerRequest) { // Do stuff // _customerRepository.SomeMethod(someParameter); } }
The problem is that as your WCF Service is instantiated by the WCF plumbing, you don't have any control over the creation of this class. How do you "inject the dependency"? How do you supply the "ICustomerRepository" to the "CustomerService"? If you are using the Windsor Container part of the Castle framework (http://www.castleproject.org/) as your Component Container, it has a Facility that enables us to do this.
Using the "CustomerService" example above, you need to do three things in your Web Services project.
1. Modify the .svc file
Create your "CustomerService.svc" file as follows:
<%@ ServiceHost Service="CustomerService" Factory="Castle.Facilities.WcfIntegration.WindsorServiceHostFactory, Castle.Facilities.WcfIntegration" %>
Note the differences between a standard svc file.
2. Modify your Global.asax
Next you need to instantiate a Windsor Container, do this in a Global.asax file as follows (you might have to add one to your project):
public class Global : HttpApplication { private readonly IWindsorContainer _container = new WindsorContainer(new XmlInterpreter()); protected void Application_End(object sender, EventArgs e) { if (_container != null) _container.Dispose(); } protected void Application_Start(object sender, EventArgs e) { WindsorServiceHostFactory.RegisterContainer(_container.Kernel); } }
3. Configure Castle
Configure Castle in the usual way, you need to include your "CustomerService" and "CustomerRepository" classes in the configuration. An example is as follows:
<configSections> <section name="castle" type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor" /> </configSections> <castle> <components> <component id="CustomerRepository" service="Acme.PetSop.ICustomerRepository, myAssembly" type="Acme.PetSop.CustomerRepository, myAssembly" /> <component id="CustomerService" service="Acme.PetSop.ICustomerService, myAssembly" type="Acme.PetSop.CustomerService, myAssembly" /> </components> </castle>
Please note that your "Service" value in the .svc file must match the "id" value in the Castle configuration.
You need to have the "Castle.Facilities.WcfIntegration.dll" assembly referenced by your Web Application project. At the time of writing this assembly is not in the latest Castle release and can only be found in the nightly builds.
The Castle documentation for the WCF Facility can be found here: http://www.castleproject.org/container/facilities/trunk/wcf/index.html
Saturday, 16 February 2008
Using the MSTest AspNetDevelopmentServer Attribute
[TestClass]
public class MyTestClass
{
[TestMethod]
[AspNetDevelopmentServer("name", "path")]
public void MyTestMethod()
{
// Do stuff
}
}
You might be tempted to put the "name" and "path" properties in constants somewhere. Unfortunately if you do this, the "AspNetDevelopmentServer" Attribute will cease to function and the ASP.NET Development Server will not be activated when your tests run. Why is a mystery. So, keep the property values as hard-coded strings in-line.
Friday, 15 February 2008
Installing Visual Studio 2005 Extensions for .NET Framework 3.0 after Visual Studio 2008
If you come to install the Visual Studio 2005 Extensions for .NET Framework 3.0 after you have installed .NET Framework 3.0 SP1 or Visual Studio 2008 (which installs .NET 3.0 SP1) then you will receive get a message saying you need to have .NET Framework 3.0 installed (as in, no Service Pack). Obviously you can't because you'll have to un-install/re-install a whole chain of stuff.
A small registry hack will let you re-try the installation, add the following to your registry:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{15095BF3-A3D7-4DDF-B193-3A496881E003}]
"DisplayName"="Microsoft .NET Framework 3.0"
This will fool the installer. I'd recommend removing the registry entry afterwards (that's what I did).
More details here: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2550726&SiteID=1
Sunday, 27 January 2008
Extending MSTest
I have created a project on CodePlex hosting the solution which supports VS2005 and VS2008 (link at the end). The CodePlex release contains MSIs plus the full source code.
The MSTest extensions Attributes are as follows:
- TestTransaction – this provides equivalent functionality to MbUnit’s much lauded “RollBack” attribute.
- ExpectedExceptionMessage – this is an alternative to MSTest’s built-in “ExpectedException” Attribute. The built in “ExpectedException” Attribute is broken, it allows you to provide a message which you would expect is the exception message that is thrown by the expected type. But it isn’t. It’s actually a message that is displayed to the user in the test results log which is very confusing. This alternative allows you to supply the exception message. If the exception message thrown by the Test Method does not match the message in the ExpectedExceptionMessage Attribute, then the test fails.
- TestTimer – this allows us to put a timer on the unit tests so if a unit test takes longer than the time specified in the Attribute then the test fails.
An example usage of the custom Attributes for MSTest are as follows:
[TestClass]
public class TestTransactionAttributeTest : MSTestExtensionsTestFixture
{
[TestMethod]
[TestTransaction]
public void SomeTest1()
{
// Do database stuff, will be
// rolled back after test ends.
}
[TestMethod]
[TestTimer(10)]
public void SomeTest2()
{
// Do stuff, if it takes longer
// than 10 milliseconds the test
// will fail.
}
[TestMethod]
[ExpectedExceptionMessage(typeof(MSTestExtensionsException), "Message.")]
public void SomeTest3()
{
throw new MSTestExtensionsException("Message.");
// This test passes
// (see above comments).
}
}
Please note there are no references to any xUnit frameworks! All that is required is to inherit from “MSTestExtensionsTestFixture” and to decorate the Test Methods with the relevant Attribute.
Here’s how we get there...
A comprehension of Aspect Oriented Programming (AOP) is needed to understand how this all fits together. I won’t go into AOP in detail as there are many on-line resources that do a much better job than I would. This is as good a place as any to start: http://en.wikipedia.org/wiki/Aspect-oriented_programming.
MSTest, like the xUnit testing frameworks, uses Attributes on Classes and Methods to specify tests and their behaviour. AOP uses the same style of Attributes on Types to extend their behaviour. If you were building your own application, you might use a framework such as Spring.NET which would provide you with a transparent AOP mechanism. Unfortunately, as MSTest is effectively “closed” (there are no extension points) we don’t have any such options. We have to wire up the AOP features ourselves.
The only way to implement AOP is to use the following objects from the .NET Framework:
- System.ContextBoundObject – the object that you wish to decorate with Attributes as a means to change the behaviour must inherit from this class.
- System.Runtime.Remoting.Contexts.ContextAttribute – Attributes inheriting from this Attribute will be called at run-time when the type that they are decorating is called.
The combination of these two objects will allow us to intercept method calls. If we can intercept calls to Methods, we can intercept the calls to Test Methods and modify their behaviour. Every one of our Test Classes (or Fixtures if you prefer) will need to inherit from “ContextBoundObject” and be decorated with our own specialised “ContextAttribute”. Instead of having to do this every time we write a Test Class, we’ll create a Class from which we can inherit when we want to write a Test Class. We’ll call this base class “MSTestExtensionsTestFixture” (as per the previous examples).This is as follows:
[MSTestExtensionsTest]
public class MSTestExtensionsTestFixture : ContextBoundObject
{
}
The “MSTestExtensionsTest” Attribute that this base Test Class is decorated with needs explaining. The “MSTestExtensionsTest” Attribute inherits from the “ContextAttribute” mentioned above. The “ContextAttribute” class has a virtual method called “GetPropertiesForNewContext” which we override. This method allows us to add “Aspects” to the context (see above link for a detailed description of Aspects and other AOP concepts). These “Aspects” will intercept Method calls i.e. when the Test Methods are executed, allowing us to change their behaviour. The important “MSTestExtensionsTest” Attribute code is as follows:
[AttributeUsage(AttributeTargets.Class)]
public sealed class MSTestExtensionsTestAttribute : ContextAttribute
{
...
public override void GetPropertiesForNewContext(IConstructionCallMessage msg)
{
if (msg == null)
throw new ArgumentNullException("msg");
msg.ContextProperties.Add(new TestProperty<TestTimerAspect>());
msg.ContextProperties.Add(new TestProperty<TestTransactionAspect>());
msg.ContextProperties.Add(new TestProperty<ExpectedExceptionMessageAspect>());
}
...
}
The "TestProperty" is a generic Class to reduce the amount of boiler plate code in each Aspect Class. I will skip this for the sakes on brevity, please look at the attached source code for details.
Fast forwarding, this is what an Aspect looks like:
public class MyAspect : TestAspect<TestTimerAttribute>, IMessageSink, ITestAspect { ... [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)] public IMessage SyncProcessMessage(IMessage msg) { if (msg == null) throw new ArgumentNullException("msg"); // The following line is the call // to the actual method we have // intercepted. We can do stuff // before we call this or after. // This lets us change behaviour. IMessage returnMessage = _nextSink.SyncProcessMessage(msg); return returnMessage; } ... }
Please review the in-line comments above. If this code was used as-is, it would simply call the Method that had been intercepted and we would notice no change in behaviour. However, we can add code before and/or after the call to “SyncProcessMessage” to do whatever we wish. This is the point at which we add our custom code to change the behaviour of the calls to the Test Methods.
From the above code, the “TestAspect” Class is another Class containing boiler plate code which I will skip over and the “ITestAspect” Interface is an Interface that our Aspects must satisfy.
An Aspect must be accompanied by an Attribute, an Attribute is simple and is essentially a placeholder for properties and ensures an Aspect is called. An example Attribute is as follows:
public sealed class MyAttribute : Attribute { private string _someProperty; public MyAttribute(string someProperty) { _testLength = someProperty; } public string SomeProperty { get { return _someProperty; } } }
And bringing it all together, if we were to use our (rather useless) Attribute it would look like so:
[TestClass]
public class MyTest : MSTestExtensionsTestFixture
{
[TestMethod]
[MyAttribute("some value")]
public void SomeTest()
{
// Unit test code.
}
}
Summary
I have skipped over the details of AOP as I would only be repeating other resources you can find on-line. However, I hope I’ve given you a taste of how the solution was implemented. Full source code is available from the CodePlex project
I think this shows that MSTest can be extended and via this mechanism can match a lot of the features of the xUnit frameworks. If you want to make further extensions, all you need to do is implement you own "TestAttribute" and an accompanying "TestAspect". Inherit from the "MSTestExtensionsFixture" and apply your Attribute and you are good to go.
Note the CodePlex solution supports VS2005 and VS2008. With the extensions that are possible and the performance improvements in VS2008 (MSTest is noticeably faster), then MSTest is not such a poor cousin to the xUnit frameworks anymore.
MSTest...it’s not all that bad, honest!
The CodePlex project hosting the solution can be found here: http://www.codeplex.com/MSTestExtensions
Callum
Blog Archive
-
▼
2008
(23)
-
►
October
(7)
- Using a custom dictionary for FxCop in Visual Stud...
- Professional Developer Conference 2008 - Day One S...
- Windows Server 2008 as a workstation (Part 3)
- Windows Server 2008 as a workstation (Part 2)
- Windows Server 2008 as a workstation
- Repairing the .NET Framework 2.0 and 3.0 on Window...
- Visual Studio Team System Developer & Database Edi...
-
►
October
(7)