Eric's Blog

Day to day experience in .NET
Welcome to Blogs @ IRM Sign in | Join | Help
 Search

Disclaimer

The content of this site is my own personal opinion and does not in any way represent my employer, it's subsideries or affiliates. These postings are provided "AS IS" with no warranties, and confer no rights.

This Blog

How to Use SchemaImporterExtension for DataSets

I recently blogged about the much improved Add Service Reference dialog in Visual Studio 2008. If you have DataSets exposed in your web services it will still generate new Datasets from the schemas and not reuse your existing DataSets even if you have a reference to the DataSet-project. The new dialog handles this without problem for you DataContract-classes though.

The solution to the problem is to implement a SchemaImporterExtension class and for DataSets you must override the ImportSchemaType method with the most arguments, because that is what gets called for complex types like DataSets. Here is a short guide how you could do this:

  1. In your project with the DataSets add a new class and call it DataSetSchemaImporterExtension and let the new class inherit from SchemaImporterExtension.
  2. Override ImportSchemType like this:
    public class DataSetsSchemaImporterExtension : SchemaImporterExtension
    {
        public override string ImportSchemaType(XmlSchemaType type, XmlSchemaObject context, 
    XmlSchemas schemas, XmlSchemaImporter importer,
    CodeCompileUnit compileUnit, CodeNamespace mainNamespace,
    CodeGenerationOptions options, CodeDomProvider codeProvider) { if (type != null) { foreach (XmlSchema schema in schemas) { const string rootNamespace = "http://YourUniqueSchemaThatAllDataSetUses/"; if (schema.TargetNamespace.StartsWith(rootNamespace)) { mainNamespace.Imports.Add(
    new CodeNamespaceImport(
    typeof(AClassInTheSameNamespaceAsTheClasses).Namespace
    )); return schema.Id; } } } return base.ImportSchemaType(type, context, schemas, importer,
    compileUnit, mainNamespace, options, codeProvider); } }
  3. The following is worth noting about the code above. I recommend you to have a namespace other than tempuri.org for the datasets because this class will be used every time you set a reference in visual studio no matter for which project you add a reference. Change AClassInTheSameNamespaceAsTheClasses to one of your dataset classes and I use this so that the namespace string will not be hardcoded if the (.NET) namespace for the datasets changes. schema.Id will have the same string as the name of the Dataset class.
  4. The Dataset assembly must be available in the GAC and one easy way to ensure that after each compile is to add a post-build event with the following:

    gacutil /i $(TargetPath) /f

    Notice: To be able to add an assembly in the GAC it must have a strong name, which can also be set up in project properties.
  5. After compiling the project it's time to register the new class in machine.config so that .NET knows about it when adding service references. Open machine.config and move to the very bottom and paste the following just before the configuration endtag.
      <system.xml.serialization>
        <schemaImporterExtensions>
          <add name="EIO.Medlemsservice.Dto"
               type="DataSetProject.DataSetsSchemaImporterExtension, DataSetProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=YourPublicKey"
               />
        </schemaImporterExtensions>
      </system.xml.serialization>
    
Published den 20 mars 2008 11:31 by ericqu
Filed under: , ,

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

No Comments

Leave a Comment

(required) 
(optional)
(required) 
Submit
Powered by Community Server, by Telligent Systems