Here are 3 quick lessons to get you started using  the DotDiff Library.

Attached Project (vs 2008) Tutorial_DotDiff1.zip (67.29 kb)

Lessons

  1. simple compare and merge
  2. Generate a Diff Gram
  3. Advanced Compare and Merge

Common Setup

Before we start any of the lessons lets go over the common set up  steps, which are as follows:

//Step 1, create an instance of the compare engine.
XmlCompare xmlCompare = new XmlCompare();

//step2, load in the documents
xmlCompare.LoadOldDocXml(File.ReadAllText("Old Xml file"));
xmlCompare.LoadNewDocXml(File.ReadAllText("New Xml file"));

//Step 3, run the compare Engine.
xmlCompare.Compare(); //yep you have just compared these documents.

From this point forward you can now:

  • Look at the Differences and merge them back into the OldXml (Lesson 1) 
  • Generate a Diff Gram AKA a Difference Graph (Lesson 2)
  • Re-Compare and other changes.

Lesson 1 

Lesson 1, is to simply compare 2 Xml files and merge a single change. start of by following the common setup, and then you can do the following:

//now lets copy of only one of the changes
DiffInstance diffInstance = xmlCompare.Differences[0];

Console.WriteLine("About to merge the following chnage: {0}, which is {1}",
    diffInstance.XPath, diffInstance.Difference.ToString());

xmlCompare.MergeNode(diffInstance); //Merge the selected change back into the oldXml doc
xmlCompare.UpdateDifferences(); //cleans up the Differences collection.

The above code, just merged the first difference into the OldXml document. That seemed simple enough

Lesson 2

Lesson 2 looks at creating a Diff Gram, you may ask what is a diff gram? Well its the Xml which only holds what is different between the New and Old Documents, it will not contain any information which both contain. making it nice and compact (helpful for updates). As with Lesson 1, follow the common setup steps and proceed with:

//Now we can Generate the Diff Gram
XmlDocument DiffDoc = xmlCompare.GenerateDifferenceGraph(); //Simple Enough

thats it, you have just created the Diff Gram, now that was not too hard :D

Lesson 3

Lesson 3 uses the advanced feature of the "IdNode", consider the following XML

<book >
  <Id>1</Id>
  <title lang="eng">Harry Potter</title>
  <price>29.99</price>
</book>

note the child node called "Id", this as you can guess is the Identifier node of the Book object. If you try and compare normally with DotDiff, it cannot tell the difference between book 1 and book 2, unless you do the following.

//Step 1, create an instance of the compare engine.
XmlCompare xmlCompare = new XmlCompare();
xmlCompare.IdNode = "Id"; //Set the name of the Id Node

This small alteration to step 1 in the setup will notify DotDiff you have child nodes with the name of "Id" as the Identifiers. You can now compare as you did before (Lesson 1) and generate Diff grams as in lesson 2

I hope this sheds some light on the use of this Library.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

I have written code for open source before, but this is my first full (small) project which I have released.

Presenting, Pause for effect, DotDiff, (first day see's 12 downloads!)

If you remember the sandbox compare tool I wrote way back last year, I have neaten some of the code up added in a Diff Gram feature and released the code on codeplex. Feel free to download it today.

Please Tell me what you think of it. Laughing, yes i know about the lack of documentation, but i have included a sample interface and comments on the code.

Hope you like it.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

SandBox Compare CTP (dbproj)

Published 6/1/2008 by Dave in dotNet | Projects
Tags: ,

Sandbox Compare is for use with dbproj files, which are Database project files generated with DBPro (not tested on VS 2008 version)

TOC

File
Screen shoot
Features
Requirements
What is SandBox Compare?
What is the Point?

 

File: SandBoxCompare.zip (16.35 kb)
(note this is Beta software! Highly reconmend backing up the dbproj file before saving over it)

Screen shoot:

Features:

  • Highlights and has a count for the number of differences
  • Highlights and has a count for the missing elements (nodes present in the user file but not the main)
  • Copy the selected node (click on a node its information is shown in the bottom right corner)
  • Copy all differences and missing nodes
  • shows the Xpath for selected the node (I like that one :) )
  • allows the user to specify a different output (Highly recommend backing up the dbproj before saving over it)

Requirements

  • .Net 2 framework

What is SandBox Compare?

It’s a very small tool, which allows the developer to compare the contents of his/hers dbproj.user file to the dbproj file. The GUI will highlight inconsistencies allowing the user to easily scroll to the difference and then copy the required change from the dbproj.user to the dbproj file.

Whats the point?

Well to answer this one, you will have to know why there are 2 files, not just one. Well the dbproj file is the main one, this will be saved in Source control and be used by the build server (thus keeping this upto date is critical). On the other hand the dbproj.user is like a "Sandbox" it can differ slighlty between developers where the developer may want or require a slightly different settings.

"This is done this way, because target database and target connection are deployment artifacts which most of the time very by user. You can set a value in the dbproj file, if you want to do this, mainly because you would be using something a like a build server like Team Build which does not have a dbproj.user file.-GertD"

Taken from
<http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1603131&SiteID=1>

On the local development box (with lets say VS 2005 and DB Pro), the developer can alter the project properties, however some settings will be persisted into your dbproj.user file. (Creating a safe sandbox to test new settings) The combination of both files is used to compile and deploy from the developer box. However when it comes to the updating the dbproj file to save into Source Control, the developer will have to manually look at both files in a text editor and copy the new (required) settings over. Now this is where SandBox Compare comes in, you can now open the 2 files to be shown the differences highlighted for you. Then it’s all up to you to change the file by clicking on a button! Phew no need to look at 100's of lines of XML :P

I hope you like it!

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Well using this awesome blog, i noticed that it can easily handle extension from other coders. Well this lead me to thinking of building a Windows/Console Proof of Concept (PoC) project. The goal was to see how to engineer a program which can use plug-ins (developed by others) and instantly use them without the need to recompile the code. Thus a truly pluggable program. Well here is the good news, its easier than I had thought to do it with .Net, so lets start.

My PoC is split into 3 projects

  1. interfaceLib (class lib) - this stores all the public interfaces supported by the application.
  2. Plugin (Class lib) - a very simple plug in (Hello world, what else)
  3. PlugControlApp (Win app) - this is the main application, which will be able to load in the Plug in and use it.

Why do i have the interface as a different project?.
1. allows you to only share the interface code
2. allows developers to save/reference only the interfaceLib project, and be able to build and compile their plug-in
3. keeps things a little simpler (well it did in this example.)

1. interfaceLib  (Design by Interface)

If you have used Design Patterns or the Enterprise Library, you may note the increase in Design by interface (hopefully you are very used to this idea). if your note i really would recommend googling this (I may write an example app at a later date to demo this concept). ANYWAY going off track....

In my example I want to be able to

  • Find what version of my application the plug is written for
  • Find the Name of the plug in
  • Have a DoSomthing function which takes in a string and returns a string.

Here is the class Diagram:

I decided to split them into 2 different interfaces as the Plugin interface would be useful for all my plug-ins, and the DoSomthing interface seemed more specialized.

2. Plugin - The outside world can help! YEAH!

This project can reference the interfaceLib, allowing the developer to build and compile a plug in control, with out the need to reference the actual application. For the plug in all i really wanted to do is to have a Hello world.... so to accomplish this the plug-in will need to follow these steps

  • Remember to add a reference to the interfaceLib and using statement

using interfaceLib;

  • In your class inherit off the required interfaces (DoSomthing in this case)

/// <summary>
/// Simple hello world plug-in!
/// </summary>
public class WriteHello : DoSomething
{

  • implement the methods to satisfy the contract of the interface

/// <summary>
/// using the DoSomthing interface, which the application supports.
/// </summary>
/// <param name="param">your name</param>
/// <returns>Hello 'your name'</returns>
public string DoSomthing(string param)
{
 return "Hello " + param;
}

  • Compile it

There it is, a plug in

3. PlugControlApp - Your uber cool application

Finally your application will also use 'design by interface' to implement the various plug-ins. I have built a small rig for this, which in this article i will only highlight the main points. As you application will handle things differently, and also i will include the projects zipped up for you to download.

This project will require the following using imports

using System.Reflection;
using interfaceLib; //this will describe the plug-in interface

The main routines were to load the plug in, and then use it. So lets review these

A. Loading in a plug-in (there are many different ways to do this), in my example project i store the loaded list of plug-ins in a List<Type>, and then store this in a listbox. (ListBox1)

/// <summary>
/// This will load in all the plug-in class, which
/// this application can support.
/// </summary>
/// <param name="location">The full location of the plug in.</param>
/// <returns>False, if it cannot load in any plug-in</returns>
private bool LoadPlugin(string location)
{
 bool rValue = false;
 try
 {
  Assembly a = Assembly.LoadFile(location);
  //now get all avalible publlic types.
  foreach (Type t in a.GetTypes())
  {
   //only interested in plublic classes.
   if (t.IsPublic && t.IsClass)
   {
    //does our application support the plug-in?
    if (IsSupportedInterface(t))
    {
     plugins.Add(t); //add this to the loaded plugins.
     rValue = true; //was able to load in a plug-in.
    }
   }
  }
 }
 catch (Exception ex)
 {
  //do nothing, could not load in
  //the dll, should have some logging code
  //here.
 }
 return rValue;
}

Remember you only want to be able to load in plug-ins which support your interfaces. (my load in function uses the following to do this).

/// <summary>
/// simple method to see if the plug as a interface which is supported.
/// </summary>
/// <param name="_plugin">plug in type. (class)</param>
/// <returns>True if this class can be supported.</returns>
private static bool IsSupportedInterface(Type _plugin)
{
 Assembly a = Assembly.GetAssembly(typeof (Plugin));

 foreach (Type t in a.GetTypes())
 {
  foreach (Type iType in _plugin.GetInterfaces())
  {
   if (t.Name == iType.Name)
    return true;
  }
 }
 return false;
}

B. Now as we loaded in the plug-in, you can now invoke the new way of processing the Dosomething method

firstly what I did here was to gain a reference to the class type,

//the actual class need to be referenced
Type ob = (Type) listBox1.SelectedItem;

this will allow us to create an instance of the class, using this method to create the object

/// <summary>
/// Create an instance of the object
/// </summary>
/// <typeparam name="T">Type of the object to create</typeparam>
/// <param name="_plugIn">The class as a type.</param>
/// <returns>a created instance of this class.</returns>
private static T createInsatance<T>(Type _plugIn) where T : class
{
 return (T) Activator.CreateInstance(_plugIn);
}

the following code uses some functions to create the instance (above) of the required object and then it runs the method. note that the interface is being used to do this

//note the interface
DoSomething p = createInsatance<DoSomething>(ob);
//get the user input from a textbox
TextBox text = GetControlByName<TextBox>("userInput");
if (text != null)
{
 //program against the plug-in using the
 //interface
 MessageBox.Show(p.DoSomthing(text.Text), p.Name);
}

So what does this all give you??

 

 

Files:

interfaceLib.zip (9.38 kb)

PlugControlApp.rar (39.26 kb)

Plugin.rar (11.16 kb)

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5