Tom Hollander's blog

patterns, practices and pontification

Managing Enterprise Library in your organization

Managing Enterprise Library in your organization

Rate This
  • Comments 17

As more people start using Enterprise Library, a lot of people are starting to ask some great questions about the best way to manage this resource within their organizations. Even though we designed EntLib to be used on projects in large organizations, it's probably fair to say that the installer and documentation is really focusing mainly on use on a single user's workstation. This is something that we will look at improving in the next version, but in the meantime I know a lot of people are crying out for some advice on how to deal with issues such as strong naming, versioning and deployment. So I'll have a go at describing some techniques that some customers are using successfully (in case you missed it, you should also check out the Enterprise Library Applied webcast where some real customers are describing their experiences). Of course, each organization is different and you may have a good reason for doing something different - but for most organizations, most of the time, hopefully this will make some sense:

Establish a centralized team that 'owns' and maintains Enterprise Library in your organization

Whether you have grand plans to extend and evolve the code, or whether you intend on using it pretty much as-is, it's a good idea to establish a single centralized team that owns and maintains the codebase for your organization. This will give you organization-level control over the code and avoids the situation where many teams or developers make changes to the code resulting in inconsistent, fragmented versions of the codebase. The centralized version can, and should, still evolve, but it will be much easier to manage the code, add features and troubleshoot bugs if you keep the number of versions down to a minimum.

Strong-name and version the Enterprise Library assemblies

Since Enterprise Library is shipped as source code, it wasn't feasible for us to strong-name the assemblies. However strong-naming (and the versioning that comes with the territory) is a really good idea, as it means you can determine the origin of the compiled code with confidence, and it adds additional runtime safety by ensuring that your applications only load code that you trust. Strong-naming is also a pre-requisite for installation into the GAC - so if you want to do this now, or think there is even a small chance you may want to do it later, then strong-naming is for you! Assuming you follow the previous tip and centrally maintain EntLib, strong-naming is easy. First, create a keypair (use: sn -k myorgskey.snk), and keep this key well guarded inside the central team. Then update the attributes in the AssemblyInfo.cs files for each project to refer to this key, or delete all of the attributes in these files and stick these in GlobalAssemblyInfo.cs (sorry, we should have left the attributes out of the AssemblyInfo.cs files in the first place to make this easier... next time...). Once you recompile, you're strong-named! Now just make sure you have a consistent and predictable versioning policy so that your developers can understand what is going on each time you release a new version. I won't discuss best practices for versioning here; hopefully you have some processes for versioning in your org already. If not, we can discuss this some other time!

Give your developers access to the source code and accept suggestions and improvements

So if you maintain EntLib centrally, there's no need to give your developers access to the source code, right? Probably not. The source code is a great learning tool, and you should also encourage your developers to explore the code and come up with suggestions to improve it. So drop the source out of planes (we do!) - but make sure you have processes for accepting good changes into the official version, and try to prevent individual developers or teams to make random changes in their own versions (again, to avoid fragmentation and maintenance problems). And if you strong-name the official version, it will be easy to tell whether people are using the official version or something else.

Deploy Enterprise Library assemblies as a part of your applications

When it comes to deployment, you can choose to deploy a single shared copy of the EntLib assemblies to the GAC, or you can use private assemblies deployed with your applications. While there are pros and cons to both methods, in general I would generally recommend the latter, as it you can get fine-grained control over the assemblies loaded by each app without dealing with complex things like binding redirects and publisher policy. If you choose to do it this way, it probably doesn't make sense to deploy Enterprise Library as a unit to your servers. Instead, just include whatever assemblies you need (which most likely won't be all of them) in the deployment package. If you are using an MSI for deployment, this will run the EntLib assembly installers (to install the instrumentation) automatically. If not, you should run installutil over your assemblies after deployment.

Update (February 7th, 2006): Paul Linton pointed me to KB article 324519 which states that there are known issues with using strongly-named assemblies outside the GAC in ASP.NET 1.1 apps. So you should actually either strong-name AND GAC-deploy the assemblies, or leave then unsigned, private assemblies in ASP.NET 1.1 applications.

Once again, these tips aren't for everyone - so if you have found other approaches that work well for your environment, feel free to comment and share your experiences with everyone else.

This posting is provided "AS IS" with no warranties, and confers no rights.

  • Deploying the assemblies with the app would be preferred, at least in my experience with sysadmins. For a while at my previous employer, the admins (both DBAs and System) had to migrate from old servers to new ones, and it is amazing the amount of cruft they had to deal with and the number of dependencies (undocumented of course) that they had to track down.

    After all was said and done, though, things that used to take 2 hours to run completed in 5 minutes. And it wasn't just from the hardware improvements!
  • Todd has a great blog post describing how to manage Enterprise Library in an organization. We only have 2 people on this project I lead and really need these guidelines. If you are in a larger organization or team that...
  • Errm ... wouldn't it be better to use the GAC? I'm retooling all of our web applications to use EL ... isn't it better to have all of them refer to the same assemblies in the GAC than for each one to have a copy ... if we have 15 projects, that's a lot of copies we shouldn't need.

    Also, I'll probably have to extend the EL to cover our custom authentication scheme.

    Of course the question I haven't answered yet is, how do you get ASP.NET projects to reference assemblies in the GAC?

    Thanks for any insights.
  • Hi Adam -

    As I said, it depends on what you are doing, and I was generalizing. If you have many apps on the one machine, and you want to minimize the number of copies of shared components, that is what the GAC is good for. However this does sometimes complicate versioning when you want to upgrade different apps to use a new version at different times. But yes, there are definitely times when the GAC is the right way to go.

    Regarding your question about ASP.NET apps referencing GAC assemblies, Visual Studio doesn't (easily) let you reference assemblies from the GAC - you need to point to a copy of the assembly in the filesystem. However at runtime your application will look for the assembly in the GAC first, providing it can find a match with the right version/culture/public key token.

    Tom
  • Best of the Blogs - Ian Smith reviews the best of the last week's web development blogs so that you don't have to. Week ending 10th April 2005. Whidby, Visual Studio Team System, Visual Studio 2003, Training, Productivity Enhancers, Front-End Development and more...
  • I have tried compiling on several machines, and I am unable to because two referenced components (nunit.framework and IBM.Data.DB2) can never be found (in all installations). Are these files missing from the download? And if I can't compile, I can't create my own strong named assembly so I am kind of at a dead end. Has anyone else had this problem?
  • Anoymous II:

    The missing references don't exist in the Enterprise Library package. However all is not lost - you don't actually need these to successfully compile EntLib.

    First, NUnit is only required if you are using a project configuration that includes the UNIT_TESTS directive. The default Debug and Release configurations don't include this directive, so it should compile by default. If you do want to use the unit tests, you can download NUnit from http://www.nunit.org.

    Second, you only need IBM's DB2 provider if you want to compile the EntLib DB2 plug-in and use the DAAB against DB2. If you want this you'll need to get the DB2 provider from IBM. If you don't want to do this, don't compile the assembly. We don't actually include the DB2 project in the EnterpriseLibrary.sln file, but it does exist in Data.sln.

    Tom
  • Thanks for your reply. You are correct in that I don't need or want NUnit or DB2. How do I compile as you suggest?

    If I open src/Data.sln and try to compile in debug or release, it tells me the DB2 reference is missing, and I get a bunch of compiler errors like

    "C:\Program Files\Microsoft Enterprise Library\src\Data\DB2\AssemblyInfo.cs(16): The type or namespace name 'IBM' could not be found (are you missing a using directive or an assembly reference?)"

    How do I compile without these? I can't create a strongly named assembly for my GAC without compiling, and I am not clear on what I need to do to get the compile to work. Thanks.
  • I think I got it. I just deleted that part of the solution. Then I added the SNK path to the AssemblyKeyFile() lines in the the three AssemblyInfo.cs files and compiled. I dropped all three .dll files into C:\WINDOWS\assembly, and the GAC took them, so I assume all is good.
  • Excellent post Tom and very timely for us. It's always a challenge to manage common components but good suggestions here to follow especially around extending the libraries. Thanks!
  • Excellent post Tom and very timely for us. It's always a challenge to manage common components but good suggestions here to follow especially around extending the libraries. Thanks!
  • I'm a newbie to the enterprise library but just discovered one little gotcha when strong naming the Configuration assembly specifically. The configuration file itself contains the full assembly descriptor of the Configuration assembly, including public key token. You must replace 'PublicKeyToken=null' with 'PublicKeyToken=xxxxxxxxxxxx' where xxxxxxx is of course the public key token of your now strongly named Configuration assembly. Failure to do so will result in a run-time assembly binding error and much confusion.

    This is perhaps obvious to others but was not to me (at least not initially), so i offer it as a public service announcement to others who may hit the same issue.
  • What file specifically did you have to modify the PublicKeyToken=null to the key that of your component? I'm having difficulty determining which file is being referred to in the post.
  • I rebuilt the E/L, removing the AssemblyKeyFile lines from each AssemblyInfo.cs file and adding the key file link to the GlobalAssemblyInfo.cs file.

    The project rebuilt fine (BuildLibrary.bat) and then I copied the assemblies into the bin folder (CopyAssemblies.bat).

    With reference to the comment about the PublicKeyToken=null, I also found a problem here for projects I had previously configured with the E/L configuration file.
    For such projects an exception is thrown by the config tool when trying to open the project. This is due to the config files referencing E/L assemblies before they were string named.
    I edited the confid files for my projkects and updated any PublibKeyToken=null entries to the correct value for my E/L strong named assemblies and now they all open up fine.
    (also, any new configs are made with the correct keys).
  • follow up to the question about my post and which file the PublicKeyToken entry is in: the configuration file i am referring to is the main application configuration file (ie. App.config for a WinForms app) plus any config files referenced by App.config (like dataConfiguration.config in my case).

    The lines in App.config looks like:

    <configSections>
    <section name="enterpriselibrary.configurationSettings" type="Microsoft.Practices.EnterpriseLibrary.Configuration.ConfigurationManagerSectionHandler, Microsoft.Practices.EnterpriseLibrary.Configuration, Version=1.0.0.0, Culture=neutral, PublicKeyToken=0d095c9e5ddafc0d" />
    </configSections>
Page 1 of 2 (17 items) 12