Bruce Lee's WebLog
Bruce Lee's personal blog. Just record my thoughts and everything here.
Tuesday, June 08, 2004
PrivateObject Unit Tester
AndrewSeven was kind enough to direct me to a blog by James Newkirk briefly introducing the PrivateObject class available at part of the VS Team System framework.
I was intrigued enough to start investigating and ended up implementing what I think is a close interpretation of this class, shown below.
The primary interface is the constructor which accepts an assembly qualified type name as the first parameter (used by Type.GetType()). The second parameter is optional and is passed as the arguments to instantiate the type; these arguments determine the constructor signature to choose.
As documented in the Type.GetType() method, the qualifiedTypeName should be of the form MyNamespace.MyClass,MyAssemblyBaseName.
Here's the code:
using System;
using System.Reflection;
using System.Security.Permissions;
#region .
/// <summary>
/// This utility class uses reflection to wrap an instance of a/// class to gain access to non-public members of that class.
/// This is an internal utility class used for unit testing.
/// </summary>
#endregion
public class PrivateObject
{
private const BindingFlags bindingFlags= BindingFlags.Instance | BindingFlags.NonPublic;
private Type type; // type of class to manage
private object instance; // managed instance of type
private ReflectionPermission perm; // for non-public members
#region .
/// <summary>
/// Initializes a new instance wrapping a new instance of the/// target type. One PrivateObject manages exactly one instance
/// of a target type.
/// </summary>
/// <param name="qualifiedTypeName">The qualified name of the type./// This should include the full assembly qualified name including
/// the namespace, for example "MyNamespace.MyType,MyAssemblyBaseName"
/// where MyNamespace is the dotted-notation namespace, MyType is the
/// name of the type and MyAssemblyBaseName is the base name of the
/// assembly containing the type.
/// </param>
/// <param name="args">An optional array of parameters to pass to/// the constructor. If this argument is not specified then the
/// default constructor is used. Otherwise, a constructor that
/// matches the number and type of parameters is used.
/// </param>
#endregion
public PrivateObject (string qualifiedTypeName, params object[] args)
{
perm = new ReflectionPermission(PermissionState.Unrestricted);
perm.Demand();type = Type.GetType(qualifiedTypeName);
Type[] types = new Type[args.Length];
for (int i=0; i < args.Length; i++)
{
types[i] = args[i].GetType();
}instance = type.GetConstructor(bindingFlags,null,types,null).Invoke(args);
}
#region .
/// <summary>
/// Gets the instance of the managed object.
/// </summary>
#endregion
public object Instance
{
get { return instance; }
}
#region .
/// <summary>
/// Gets the value of a non-public field (member variable) of the/// managed type.
/// </summary>
/// <param name="name">The name of the non-public field to/// interrogate</param>
/// <returns>A value whose type is specific to the field.</returns>
#endregion
public object GetField (string name)
{
return type.GetField(name,bindingFlags).GetValue(instance);
}
#region .
/// <summary>
/// Gets the value of a non-public property of the managed type.
/// </summary>
/// <param name="name">The name of the non-public property to/// interrogate.</param>
/// <returns>A value whose type is specific to the property.</returns>
#endregion
public object GetProperty (string name)
{
return type.GetProperty(name,bindingFlags).GetValue(instance,null);
}
#region .
/// <summary>
/// Invokes the non-public method of the managed type.
/// </summary>
/// <param name="name">The name of the non-public method to invoke.</param>
/// <param name="args">And optional array of typed parameters to pass to the
/// method. If this argument is not specified then the routine searches
/// for a method with a signature that contains not parameters. Otherwise,
/// the procedure searches for a method with the number and type of parameters
/// specified.
/// </param>
/// <returns>A value who type is specific to the invoked method.</returns>
#endregion
public object Invoke (string name, params object[] args)
{
Type[] types = new Type[args.Length];
for (int i=0; i < args.Length; i++)
{
types[i] = args[i].GetType();
}return type.GetMethod(name,bindingFlags,null,types,null).Invoke(instance,args);
}
#region .
/// <summary>
/// Sets the value of a non-public field (member variable) of the managed type.
/// </summary>
/// <param name="name">The name of the non-public field to modify.</param>
/// <param name="val">A value whose type is specific to the field.</param>
#endregion
public void SetField (string name, object val)
{
type.GetField(name,bindingFlags).SetValue(instance,val);
}
#region .
/// <summary>
/// Sets the value of a non-public property of the managed type.
/// </summary>
/// <param name="name">The name of the non-public property to modify.</param>
/// <param name="val">A value whose type is specific to the property.</param>
#endregion
public void SetProperty (string name, object val)
{
type.GetProperty(name,bindingFlags).SetValue(instance,val,null);
}
}
Sunday, June 06, 2004
.NET Tool/Control vendors/creators: new directory site: www.developerfood.com!
A good friend of mine, Scott Wallace, has created a new .NET tool/control directory site: http://www.developerfood.com! If you are a tool / control vendor or a freeware/open source tool/control programmer, feel free to add your tool/control to the directory. The site is free, doesn't sell the controls / tools it lists nor is it affiliated with a tool/control vendor.
I think it is a great initiative and it takes just a few minutes to get your tool/control enlisted. One for the bookmarks!
Wednesday, June 02, 2004
SQL Server Developer Center
This is nice:
Microsoft has launched a SQL Server Developer Center. [by way of Scott Swigart/Early Adopter]
Looking forward to some very good resources from this site.
Monday, May 31, 2004
Gmail is in trouble
Gmail is in trouble:
Anti Gmail Legislation
California Senate Passes Watered Down Anti-Gmail Bill
So the California state government is passing legislation controlling an as-yet-unreleased technology service. I don’t think I’ve ever heard of such a thing before.
Via Dino. Rob is on the news today
Rob Howard, one of brains behind the excellent provider model in ASP.NET 2.0 (sure, not just that...) leaves MS. I want to wish all the best of luck (and why not, a LOT of fun) to Rob for the new venture: Telligent Systems. As of today, the Web site contains just a GIF but I wonder which technology are they using to build the site. Maybe JSP? <g>
PS: I also wondered why Telligent Systems and not, a more natural for me, Intelligent Systems. Elementary, Dr. Watson! Intelligent Systems already exists; both with .com and .net. It doesn't exist as .it, but who cares :-)
Saturday, May 29, 2004
Tuesday, May 25, 2004
Sauce Reader, another RSS aggregator to try
Wow, another cool news aggregator was released over the weekend: Sauce Reader.
It also has integration with the Windows Messenger client (not yet the MSN one). I have that on my desk at work, so will try it there.
WSE 2.0 Tracing Utility
Services Enhancements 2.0 (go here href="http://msdn.microsoft.com/webservices/building/wse">http://msdn.microsoft.com/webservices/building/wse
for a download) I thought I’d publish my efforts at providing a secondary
tracing utility. WSE 2.0 has tracing facilities that can be switched on via the
configuration file which traces messages to a text file but I wanted something
that looked a little bit more like the SOAPTrace tool that shipped with he SOAP
toolkit so that I can more easily use it for demos and so on.
has flaws but if it’s of use to other people then that’s great and I’ll share it
here – the usual caveats apply around not being intended for any particular
purpose and coming without warranty implied or explicit.
is the URL for download – I’ve not included the source at this point but I can
do that if someone’s keen to get it.
WSE2.0 SOAP messaging to trace WSE2.0 messaging (be that ASMX or SOAP
messaging).
down a bit because whenever you send/receive a message if you’ve switched on
tracing I then go and send a copy of your messages over the SOAP.TCP protocol to
the tracing client.
this;
border=0>
So, to work the client
you use File->Start/Stop tracing to start the client listening for messages
and then File->Clear to clear the traces captured and the tree view will
display messages that it has traced going in or out of each process and
application domain that you have configured tracing for. You can configure
tracing to be for incoming or outgoing messages or both.
listens on soap.tcp://localhost:9999/SoapTracer. If, for some reason you don’t
want this you can change it using the Tools->Options dialog box which looks
like this;
different endpoint to listen on for those trace messages.
tracing client – note that it’s actually persisting the XML to disk in order to
use Internet Explorer to display the XML which is not very clever but was a
quick “win” for me.
applications in order to get their WSE2.0 messages traced to the tracing
client?
configuration file for the application that you want tracing for. A sample
configuration file is shipped within the MSI and looks like this (except the
real file has more comments in it);
encoding="utf-8"?>
name="microsoft.web.services2"
type="Microsoft.Web.Services2.Configuration.WebServicesConfiguration,
Microsoft.Web.Services2, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" />
name="WSETraceSettings" type="WSETracingConfig.ConfigHandler, WSETracingConfig,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=1c1f2f7177e1ff79"
/>
xmlns='urn:wsetrace-mt-com'>
<hostname>127.0.0.1</hostname>
<port>9999</port>
<endpoint>SoapTracer</endpoint>
<microsoft.web.services2>
<output>
<add type="WSETracingFilter.WSEOutputFilter,WSETracingFilter,
Version=1.0.0.0, Culture=Neutral,
PublicKeyToken=1c1f2f7177e1ff79"/>
<add type="WSEReorderPipelineFilter.WSETracingReorderOutputFilter,
WSETracingReorderPipelineFilter, Version=1.0.0.0, Culture=Neutral,
PublicKeyToken=1c1f2f7177e1ff79"/>
</output>
<input>
<add type="WSETracingFilter.WSEInputFilter,WSETracingFilter, Version=1.0.0.0,
Culture=Neutral, PublicKeyToken=1c1f2f7177e1ff79"/>
<add type="WSEReorderPipelineFilter.WSETracingReorderInputFilter,
WSETracingReorderPipelineFilter, Version=1.0.0.0, Culture=Neutral,
PublicKeyToken=1c1f2f7177e1ff79"/>
</input>
</filters>
So, the way that the tracing filter is implemented is as a filter for
the WSE 2.0 pipeline so if you want tracing to occur you need to configure it
into that pipeline. This is done through the;
<filters>
<output>
<add>
<filters>
<input>
<add>
need to have both input and output tracing – it’s entirely up to you. Note that
if you do want filtering then you have to include both add lines in each case
(explanation to follow).
<WSETraceSettings>
tracing tool (via Tools->Options) to listen on a new endpoint. If you have
done that then you need to configure that endpoint here as well or the trace
messages will not reach the tracing client. It’s important to note that if you
do include this <WSETraceSettings> element then you also need to include
the;
<configSections>
<section name=”WSETraceSettings” …
with people if anyone wants it. Happy to fix bugs for people or rework it
completely if someone spots a fundamental flaw.
CSS2 Intellisense for Visual Studio .Net
Thanks Scott for the link !
Read this article and download the required metadata file to bring CSS2 to VS.Net.
Objectspaces, WinFS and MBF all in Longhorn
I've been watching - and reading - the recent debate over the announcement to postpone the launch of Objectspaces to Longhorn by aligning it with WinFS.
Barry Gervin has a report from TechEd on this issue that ties together this decision with MBF also being moved to the Longhorn timeframe. I think it makes sense to make every effort possible to make sure that when we [MSFT] decide to put out a new data-access API, we can say that we have done everything possible to make sure that it is aligned across all layers that will build on it, and that it will provide a stable programming model for many years forward.
I don't think it is prudent to dismiss WinFS as "Just a Filesystem" that does not have anything to do with data-storage. It represents a paradigm shift in terms of connecting structured and unstructured storage, database and filesystem, and provides an object-relational model for data access - That, combined with the need to support the requirements for data access that ObjectSpaces and MBF bring to the marriage will help make WinFS suited to be the data-access platform for the future. For MBF this partnership will surely mean that we can now rely on a strong underlying persistance platform that will also be the data-storage platform of choice for Longhorn generation apps.
Talking Avalon at WinHEC
Earlier this month I had the opportunity to present the overview of Avalon at the Windows Hardware Engineering Conference (WinHEC). The conference attendees are typically independent hardware vendors, designers, and folks writing software at the software/hardware interface level. As such, there's less interest in the higher level aspects of Avalon, but there was a lot of interest in the entire graphics and media stack. So my talk focused on that. General WinHEC session information and materials can be found here.
Other Avalon graphics and media sessions at WinHEC delivered by my colleagues can be found here:
Stay tuned for another post, hopefully soon, about 3D, for which WinHEC was our coming out party.
Reporting Services: How can I deploy my report without Visual Studio?
To handle this, there is a utility called rs.exe. This utility allows the a developer to create a script utilizing Visual Basic.NET.
A sample script will follow soon.