In the UK? Have VB6 code? Check out Eric’s Resource Site

Eric has been beavering away to put together a resource site for UK companies that are working with Visual Basic 6 – click the big picture below to check it out;

image 

Some of the highlights include;

  • A great prize draw to win a free copy of a migration tool from Artinsoft or Code Architects (We have several to give away)
  • Great offers from our partners. How about a entry level great migration tool for just £199 or 25% off a full blown enterprise class tool
  • An attempt to summarise the five options you can take along witha 10 minute screencast by myself explaining the five options (and you can tell I had a cold when I recorded it!)
  • Links to the best resources to find out more
  • And a a brand new detailed article on the Interop Forms Toolkit which enables .NET forms and controls to be easily mixed with Visual Basic 6.0 forms and controls.

take a look.

Thinking about C# 4.0, VB 10 and Dynamic

I’ve been thinking a little this week about C# 4.0, VB 10 and the new dynamic abilities. That is, what happens when I do something like;

  static void Main(string[] args)
  {
    dynamic o = GetSomeObject();
    o.Add(101);
  }
  static object GetSomeObject()
  {
    return (new List<int>());
  }

Now, if you’ve seen the sessions around this (watch this one, read this document) then you’ll know that in C# 4 this code compiles and works and that a variable declared with dynamic means that the C# compiler is prepared to get into “dynamic resolution and dispatch” for variables (parameters, return values, etc) that are declared as dynamic and that can have different meanings such as;

  1. If the object is a plain .NET type then the dynamic work can be done via reflection
  2. If the object is a COM object implementing IDispatch then the work can be done via that interface
  3. If the object implements IDynamicObject (a new interface in .NET 4.0) then the work can be done via that interface and this provides a plug-in point for library writers to implement dynamic dispatch over pretty much anything they like

But…we know that VB was already pretty savvy and able to do this kind of thing. For example, this is valid VB 9 code ( I think );

  Sub Main()
    Dim o As Object = GetSomeObject()
    o.Add(101)

  End Sub
  Function GetSomeObject() As Object
    Return (New List(Of Integer))
  End Function

and so VB was already prepared to be a bit looser and do some automatic reflection (or some COM IDispatch work) so it could equally well do something like;

  Sub Main()
    Dim o As Object = GetSomeObject()
    o.Visible = True
    o.Workbooks.Add()

  End Sub
  Function GetSomeObject() As Object
    Return (Activator.CreateInstance(Type.GetTypeFromProgID("Excel.Application")))
  End Function

whereas C# couldn’t do that kind of thing without writing a bunch more code.

Now, VB 10 (watch this session, read this document) extends these “automatic reflection and IDispatch” abilities to also include the ability to call implementations of IDynamicObject so that C# 4 and VB 10 become pretty much equivalent.

However…this had me puzzling over what dynamic in C# actually means.

What does the C# compiler actually do to the type in order to say “this particular instance needs dynamic dispatch” whilst not damaging how VB (or other languages) see the same type because VB already knew how to do some of these automatic things with object instances.

It’s a pretty simple answer I think. If I take a longer winded sample as in;

  static void Main(string[] args)
  {
    SomeProperty.Add(101);
  }
  static dynamic SomeProperty
  {
    get
    {
      return (GetSomeObject());
    }
  }
  static dynamic GetSomeObject()
  {
    return (new List<int>());
  }

then all that’s really doing is;

  static void Main(string[] args)
  {
    SomeProperty.Add(101);
  }
  [property:Dynamic]
  static object SomeProperty
  {
    get
    {
      return (GetSomeObject());
    }
  }
  [return:Dynamic]
  static object GetSomeObject()
  {
    return (new List<int>());
  }

although note that the C# compiler will not let me type that code, it tells me to use the dynamic keyword. But…if I was building this in VB and then using it from C# I think I’d need to do that as in;

Public Class SomeClass

  <Dynamic()>
  Public ReadOnly Property SomeProperty As Object
    Get
      Return (GetSomeObject())
    End Get
  End Property

  Private Function GetSomeObject() As Object
    Return (New List(Of Integer))
  End Function
End Class

and then I can use that from C# as in;

    SomeClass sc = new SomeClass();
    sc.SomeProperty.Add(101);

otherwise if I wrote the VB like this without the Dynamic attribute;

Public Class SomeClass

  Public ReadOnly Property SomeProperty As Object
    Get
      Return (GetSomeObject())
    End Get
  End Property

  Private Function GetSomeObject() As Object
    Return (New List(Of Integer))
  End Function
End Class

then my C# code wouldn’t compile unless I went and did something like;

    SomeClass sc = new SomeClass();
    dynamic dyn = sc.SomeProperty;
    dyn.Add(101);

so I’m feeling a little more comfortable in knowing that when I used dynamic in C# it’s just sticking an attribute onto that usage to tell the compiler to apply its dynamic magic to interactions with that particular type – it’s not doing something like “creating a special kind of System.Object with some bit set on it which indicates dynamic usage”.

SQL 2008, Filestream, Docs from VB

Someone asked me if I had a simple sample of how to read/write documents into a database table using FILESTREAM in SQL Server 2008.

I set about it.

Firstly, I had to find out how to switch FILESTREAM on in the RTM of SQL Server. At times like this you need Bob Beauchemin to tell you how it’s done and then you can go and run code such as this once you’ve done the necessary bits in SQL Configuration manager;


exec sp_configure filestream_access_level, 2
reconfigure
go

CREATE DATABASE Documents 
ON
PRIMARY 
( 
    NAME = DocData,
    FILENAME = 'c:\temp\docs.mdf'
),
FILEGROUP FileGroup CONTAINS FILESTREAM
( 
    NAME = DocFiles,
    FILENAME = 'c:\temp\docstreams'
)
LOG ON  
( 
    NAME = DocLog,
    FILENAME = 'c:\temp\docs.ldf'
)
GO


and now I’ve got a database that can accept file stream data. Phew. Time for a simple table;

create table Docs
(
    id uniqueidentifier rowguidcol not null primary key,
    documentData varbinary(max) filestream not null,
    documentName nvarchar(1024) not null
)

Now I’ve got a table I can use something like Windows Presentation Foundation with VB to build a simple UI to allow me to add documents to the database and then edit them. Note that editing them here just means sucking out the file data, writing it to a temporary file, passing that to the Shell for editing and then saving the contents back to the database.

There ended up being too much code to paste in here as a blow-by-blow account but here’s my rather grey looking UI;

image

with a few items from my desktop that I’ve added to my database table.

The code’s pretty hacky with almost no error handling but I thought I’d share it here for download regardless.