Plug-in Edmx Code Generator Released
Holy moly releasing software is quite the process. :) After about a month or so of trying to get my Plug-in Edmx Code Generator released, I'm proud to say that it's finally out on the new Entity Framework Contribution Project (I'm a contributor, scary!). I wanted to take some time to post about this little pet project and its history.
First off, I learned a little bit about plug-in architecture from the great EntLib project. I was pretty impressed with it, so it instantly became a new tool in my toolbox.
Upon reading about how the current event hooks work for code generation in the Entity Framework, I was disappointed in the overall process. To me, if someone wants to hook into the code generation process, it should be as easy as dropping an assembly into a plug-in directory and when the EF code generator fires, it should just load all the assemblies in that plug-in directory and register the code generator with any located subscribers.
So that’s what I set out to do. Initially I had to reverse engineer the System.Data.Entity.Design.VisualStudio assembly and do all sorts of wicked code magic to make this work on my personal project. Major props to the ADO.NET team for releasing the SampleEdmxCodeGenerator, from which this new codebase is derived from.
This project is a little rough around the edges. I don’t have the time to acquire a PhD in the Lore of COM to learn how that mire works (no sir, not a fan). So, testing is sporadic, at best. I’ve attempted to make the install process as straight-forward as possible, so no reasonable developer should ever EVER have to touch the registry or go to the command-line (stay away from that filth!). It is 2008, after all. I’d like to think we’ve progressed a little in our development capacities and IQ to ever have to deal with COM or a command prompt…
Oh, am I ranting? My bad. J Let’s look at how to install this sucker, shall we?
First thing is first: THIS IS A FIRST VERSION RELEASE! This isn't exactly a production-ready piece of software. This is something that I've pieced together over the course of a couple months, and got it working to my needs, and then ported over to the Contrib(UTION) project. Things are not exactly 100% complete, but "should work" (read: "works on my machine"). I'm sure there are a lot of edge cases I may be missing, and the testing project quite frankly leaves much to be desired.
... And with that...
If you get the latest Entity Framework Contribution solution, you’ll notice that there are two new configurations within the Configuration Manager (found by right-clicking the solution and selecting Configuration Manager): Install and Uninstall. Furthermore, you can find another CPU setting for x64 machines for you 64-bit developers (as I am J).
The installation process is pretty simple:
1) Select Install configuration
2) Select the type of processor configuration of Visual Studio you have on your machine (Any CPU for 32-bit, x64 for 64-bit)
3) Build EntityFrameworkContrib.Design.VisualStudio.Install
This will build and register the DLL, and install the necessary registry settings on your machine.
How does this plug-in system work? The process works as such:
1) Create Visual Studio 2008 Class Library project
2) Create a class that implements the EntityFrameworkContrib.Design.VisualStudio.IEdmxCodeGeneratorSubscriber interface within this class library and implement your custom code within the Subscribe() method.
3) Decorate the assembly with the EdmxCodeGeneratorSubscriberAttribute attribute, like so: [assembly: EdmxCodeGeneratorSubscriber( typeof(MockCodeGenerator) )]
4) Build the assembly.
5) Place the assembly within the plug-in directory. By default this is the same directory as where the devenv.exe is found (something like C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE). You might find this is a little slow since this directory has a bunch of .dlls in it already. I’ve made it so that you can specify a plug-in directory through configuration (more on this below).
6) Set the Custom Tool for each Edmx file that you want to take advantage of this process to “PluginEdmxCodeGenerator” (without quotes, of course).
7) Right-click your .edmx file that you configured in the above step, and select Run Custom Tool.
If the stars aligned correctly, you should get a .cs built and compiled that consists of the output you expected from your custom code defined in step #2.
If you don’t like the default directory (and I don’t, so neither should you), then you can specify where you’d like that directory to be. This is where it gets a little hacky, because it does involve editing the configuration for devenv.exe. If someone is familiar with how to manage a configuration section from outside the executing assembly, I am all open for suggestion and correction. The ideal situation would be to simply drop an EntityFrameworkContrib.dll.config file right into the devenv.exe directory so that devenv.exe automatically reads configuration for EntityFrameworkContrib from this file. But alas, I couldn’t figure out how this works. So in the meantime
To set the configuration:
1) Make a copy of devenv.exe.config just in case. ;)
2) Open devenv.exe.config found in the same directory as in step #5 above (hey, it’s better than driveling through the swine that is The Registry!).
3) Add the following configuration into the <configSections> block at the top:<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=126.96.36.199, Culture=neutral, PublicKeyToken=b77a5c561934e089" > <section name="EntityFrameworkContrib.Design.VisualStudio.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=188.8.131.52, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
4) Add the following configuration right below the closing </configSections><applicationSettings> <EntityFrameworkContrib.Design.VisualStudio.Properties.Settings> <setting name="PluginDirectory" serializeAs="String"> <value>C:\ADO.NET Entity Framework Edmx Code Generation Plug-ins</value> </setting> </EntityFrameworkContrib.Design.VisualStudio.Properties.Settings>
5) Modify the <value></value> block to point to a valid directory path on your system. I’ve setup the pathing resolution within the PluginManager to resolve any environment variable specified in this value.
Yes, overall this is a pretty involved process. IMHO the good folks on the ADO.NET team should implement this pattern for their default code generator so that this functionality is all setup and ready to go out of the box. Plug-ins are the Right Thing to do and make it easy to extend provided framework functionality without having to wrestle with arcane, obsolete concepts like registry settings and COM.
Yes, I feel better now. J
I hope this helps someone out and makes code generation a little easier for the Entity Framework. If you have any questions, there is a Mock assembly included in the Contrib(UTION) project that makes use of the necessary hooks to make this sucker work. Please feel free to take a look at this, and if you still have questions, don’t hesitate to send them my way!