Inserting Class Into A Hierarchy

We will use the same A, B and C classes as in the previous example

. The goal is to insert a new class with additional members between B and C class in the hierarchy.

Let's store some class objects first:

refactoringExample.cs: StoreData
01public static void StoreData() 02 { 03 File.Delete(Db4oFileName); 04 IObjectContainer container = Db4oFactory.OpenFile(Db4oFileName); 05 try 06 { 07 A a = new A(); 08 a.name = "A class"; 09 container.Set(a); 10 11 B b = new B(); 12 b.name = "B class"; 13 b.number = 1; 14 container.Set(b); 15 16 C c = new C(); 17 c.name = "C class"; 18 c.number = 2; 19 container.Set(c); 20 } 21 finally 22 { 23 container.Close(); 24 } 25 }
refactoringExample.cs: ReadData
01public static void ReadData() 02 { 03 IObjectContainer container = Db4oFactory.OpenFile(Db4oFileName); 04 try 05 { 06 IObjectSet result = container.Get(new A()); 07 System.Console.WriteLine("A class: "); 08 ListResult(result); 09 10 result = container.Get(new B()); 11 System.Console.WriteLine(); 12 System.Console.WriteLine("B class: "); 13 ListResult(result); 14 15 result = container.Get(new C()); 16 System.Console.WriteLine(); 17 System.Console.WriteLine("C class: "); 18 ListResult(result); 19 } 20 finally 21 { 22 container.Close(); 23 } 24 }
refactoringExample.vb: StoreData
01Public Shared Sub StoreData() 02 File.Delete(Db4oFileName) 03 Dim container As IObjectContainer = Db4oFactory.OpenFile(Db4oFileName) 04 Try 05 Dim a As New A() 06 a.name = "A class" 07 container.[Set](a) 08 09 Dim b As New B() 10 b.name = "B class" 11 b.number = 1 12 container.[Set](b) 13 14 Dim c As New C() 15 c.name = "C class" 16 c.number = 2 17 container.[Set](c) 18 Finally 19 container.Close() 20 End Try 21 End Sub
refactoringExample.vb: ReadData
01Public Shared Sub ReadData() 02 Dim container As IObjectContainer = Db4oFactory.OpenFile(Db4oFileName) 03 Try 04 Dim result As IObjectSet = container.[Get](New A()) 05 System.Console.WriteLine("A class: ") 06 ListResult(result) 07 08 result = container.[Get](New B()) 09 System.Console.WriteLine() 10 System.Console.WriteLine("B class: ") 11 ListResult(result) 12 13 result = container.[Get](New C()) 14 System.Console.WriteLine() 15 System.Console.WriteLine("C class: ") 16 ListResult(result) 17 Finally 18 container.Close() 19 End Try 20 End Sub

The following class will be inserted:

D.cs
01/* Copyright (C) 2007 db4objects Inc. http://www.db4o.com */ 02using System; 03using Db4objects.Db4odoc.Refactoring.Initial; 04 05namespace Db4objects.Db4odoc.Refactoring.Refactored 06{ 07 class D: B 08 { 09 public DateTime storedDate; 10 11 public override string ToString() 12 { 13 return name + "/" + number + ": " + storedDate; 14 } 15 } 16}
D.vb
01' Copyright (C) 2007 db4objects Inc. http://www.db4o.com 02'Imports Db4objects.Db4odoc.Refactoring.Initial 03 04Namespace Db4objects.Db4odoc.Refactoring.Refactored 05 Class D 06 Inherits Initial.B 07 08 Public storedDate As System.DateTime 09 10 Public Overloads Overrides Function ToString() As String 11 Return name + "/" + number.ToString() + ": " + storedDate.ToString() 12 End Function 13 14 End Class 15End Namespace

Now C class must inherit from D. We can't change C class itself, because its data will be lost. Therefore we will create a new E class to hold C data:

E.cs
01/* Copyright (C) 2007 db4objects Inc. http://www.db4o.com */ 02using System; 03 04namespace Db4objects.Db4odoc.Refactoring.Refactored 05{ 06 class E: D 07 { 08 09 } 10}
E.vb
1' Copyright (C) 2007 db4objects Inc. http://www.db4o.com 2 3Namespace Db4objects.Db4odoc.Refactoring.Refactored 4 Class E 5 Inherits D 6 End Class 7End Namespace

When all the necessary classes are created we can copy C data into E class:

refactoringUtil.cs: MoveValues
01public static void MoveValues() 02 { 03 IObjectContainer container = Db4oFactory.OpenFile(Db4oFileName); 04 try 05 { 06 IObjectSet result = container.Get(new C()); 07 for (int i = 0; i < result.Count; i++) 08 { 09 C c = (C)result[i]; 10 E e = new E(); 11 e.name = c.name; 12 e.number = c.number; 13 container.Delete(c); 14 container.Set(e); 15 } 16 17 } 18 finally 19 { 20 container.Close(); 21 System.Console.WriteLine("Done"); 22 } 23 }
refactoringUtil.vb: MoveValues
01Public Shared Sub MoveValues() 02 Dim container As IObjectContainer = Db4oFactory.OpenFile(Db4oFileName) 03 Try 04 Dim result As IObjectSet = container.[Get](New Initial.C()) 05 For i As Integer = 0 To result.Count - 1 06 Dim c As Initial.C = DirectCast(result(i), Initial.C) 07 Dim e As New E() 08 e.name = c.name 09 e.number = c.number 10 container.Delete(c) 11 container.[Set](e) 12 13 Next 14 Finally 15 container.Close() 16 System.Console.WriteLine("Done") 17 End Try 18 End Sub

Now C classes can be safely removed from the project and all the references to it updated to E(or D). We can check that all the values are in place:

RefactoringExample.cs: ReadData
01public static void ReadData() 02 { 03 IObjectContainer container = Db4oFactory.OpenFile(Db4oFileName); 04 try 05 { 06 IObjectSet result = container.Get(new D()); 07 System.Console.WriteLine("D class: "); 08 ListResult(result); 09 10 result = container.Get(new E()); 11 System.Console.WriteLine(); 12 System.Console.WriteLine("E class: "); 13 ListResult(result); 14 } 15 finally 16 { 17 container.Close(); 18 } 19 }
RefactoringExample.vb: ReadData
01Public Shared Sub ReadData() 02 Dim container As IObjectContainer = Db4oFactory.OpenFile(Db4oFileName) 03 Try 04 Dim result As IObjectSet = container.[Get](New D()) 05 System.Console.WriteLine("D class: ") 06 ListResult(result) 07 08 result = container.[Get](New E()) 09 System.Console.WriteLine() 10 System.Console.WriteLine("E class: ") 11 ListResult(result) 12 Finally 13 container.Close() 14 End Try 15 End Sub

When performing refactoring on your working application do not forget to make a copy of the code and data before making any changes!