Linq to SQL provide build in logger that logs all select, insert, update and delete operations, it executes. Very helpful tool when something goes wrong.

You can find it under DataContext .Log property that takes TextWriter .

Most of the samples you probably would find about the logger are setting the Console.Out to it, like this:

DataContext dataContext = newMyDataContext();
dataContext.Log = Console.Out;

The more common scenario would be to write it to a text file. Changing this code to open a StreamWriter is not so hand:

string logFilePath = @"c:\log.txt";
FileStream fileStream = new FileStream(logFilePath, FileMode.OpenOrCreate, FileAccess.Write);
TextWriter textWriter = new StreamWriter(fileStream);
dataContext.Log = textWriter;

Unfortunately this code will not work properly all the time, not if you use Linq to SQL with Async calls or Parallel execution. If you have more then one thread that accessing the same file you probably get the exception "The process cannot access the file because it is being used by another process".

To overcome this problem all that need to be done is opening the file with sharing, using FileShare enum, which is the proper way to handle files when running multi threads

FileStream fileStream = new FileStream(logFilePath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite);
Unity Application Block is part of entLib 4.1, unfortunately its configuration section is not editable via entLib configuration editor. The editor probably 
will be updated in the next version of entLib 5.0, till then the best that we can do is add intelliSense to the configuration file. 
First download the xsd file of Unity from http://www.codeplex.com/unitycontributions/SourceControl/PatchList.aspx and copy that
to c:\Program Files\Microsoft Visual Studio 9.0\Xml\Schemas [for VS 2008].
After that go to your configuration file, open it for edit, open the properties, go to schemas and open the editor, check the use box for unoty.xsd
clip_image002[6] 

After that you will be able to auto complete the unit section

clip_image004[6]

The bad news is that you have to do this operation for every new configuration file you use.

Subversion (AKA SVN) is good choice for source control if you don’t want to pay for licenses.

For setting up the subversion source control for visual studio you need to do the following:

1) Install the subversion plug in - http://www.visualsvn.com/visualsvn/download/

2) for more operation and user interface install - http://tortoisesvn.net/downloads

3) for the SVN repository you have couple of choices:

a. Install one on your machine. Download and install the SVN server (http://www.visualsvn.com/server/). For this you have to be ready to do some extra install (like web server) and do some configurations. The benefit is that you have full control on the server

b. Open a SVN repository on one of the providers on the web. I found and open main at https://projectlocker.com/, you can find much more by googling "SVN host/repository". The differences between the hosts are is like everything in life – what you get in return. Much more you pay you get more security and storage. If you will choose a free one then you get up to 500M (which is more the enough for small projects) but not of those hosts are guaranty that you sources will be secured.

Bottom line, Choose the one that fits your needs.

After following those steps you will get a VisualSVN menu in your visual studio

clip_image002

As you can see there are all the common actions for source control. Update, commit, get and add solution from and to source control and more.

You can see it in more detail in the following tutorial: http://www.visualsvn.com/visualsvn/demo/

Posted by Nati Dobkin | with no comments

Last week Shani Raba and I have performed a two days session about WCF. The presentations from both days are attached.

Code will come soon.

WCF Course – First Day

WCF Course – Second Day

Posted by Nati Dobkin | with no comments
תגים:, ,

Let the code talk

public class XmlXsdValidator
{
    private static bool _isValied = true;
    public static bool ValidateXmlAgainstXsdSchema(string xmlPath, string xsdPath)
    {
        try
        {
            XmlReader xsd = new XmlTextReader(xsdPath);
            XmlSchemaSet schema = new XmlSchemaSet();
            schema.Add(null, xsd);

            XmlReaderSettings xmlReadeSettings = new XmlReaderSettings();
            xmlReadeSettings.ValidationType = ValidationType.Schema;
            xmlReadeSettings.Schemas.Add(schema);
            xmlReadeSettings.ValidationEventHandler += new ValidationEventHandler(ValidationHandler);

            XmlTextReader xmlTextReader = new XmlTextReader(xmlPath);
            XmlReader xmlReader = XmlReader.Create(xmlTextReader, xmlReadeSettings);

            while(xmlReader.Read());
            xmlReader.Close();
        }
        catch (Exception ex)
        {
            _isValied = false;
            // Write here exception massage to log
        }
        return _isValied;
    }

    private static void ValidationHandler(object sender, ValidationEventArgs args)
    {
        _isValied = false;
    }
}

There is one static method that get XML and XSD paths and return true if the xml fit the xsd schema and false otherwise.

Posted by Nati Dobkin | with no comments

 

Configuration sections are our ability as developers to interfere in the structure of our configuration file and add some custom value in it. Yoav Michaely (my team mate) and I tried to make the use of it a little simpler.

Our goals:
1) Make easy use of configuration section instance
2) To imitate the functionality of AppSetting of key value collection
3) Maybe get some extra functionality in the way – how knows…?

So let see out class declaration:

public abstract class ConfigurationSectionBase<CurrentClass> : ConfigurationSection

that would be our base configuration section class that will encapsulate some basic logic like instance initialization, type converting and more

public abstract class ConfigurationSingleSectionBase<CurrentClass> : ConfigurationSectionBase<CurrentClass>where CurrentClass : ConfigurationSingleSectionBase<CurrentClass>

t hat would be our single section class, which will get us the goals we define earlier. As you can see the generic class gets the derived class as it type

The last part that I am missing for handle the job is the configuration section name, which you usually supply hard coded. I decide to pass it as an attribute over deriving class, and there is it definition

public sealed class ConfigurationSectionAttribute : Attribute

which have only one property of SectionName

Let's see how we are using that mechanize, shell we.

[ConfigurationSection("TestSection")]
public class TestSection : ConfigurationSingleSectionBase<TestSection>
{
    [ConfigurationProperty("Prop1")]
    public string Prop1
    {
        get { return GetSectionValue<string>("Prop1"); }
    }

    [ConfigurationProperty("Prop2")]
    public int Prop2
    {
        get { return GetSectionValue<int>("Prop2"); }
    }
}

As you can see derived for out base class, add the attribute to indicate what my section name in config file and wrote some properties. As you can see I used GetSectionValue<T> method, which come from our ConfigurationSingleSectionBase class which heples to conver property to it correct type.

Now we have to register the section to our config file, the usual way,like this

As you can see we can add properties and some key value collection to our section definition. Now comes the interesting part, how would we access our section instance, as some of you will remember the way we are getting configuration section handlers is by writing code like following:

object section = ConfigurationManager.GetSection("MyCoolSectionName");
if (section != null)
    MyNewSection sec = (MyNewSection)section;
sec.Prop1;

This is not so nice code to write for every and each section, so what would we do? My answer is nothing!
Remember our derive class (TestSection) so let look what it has?

Two simple properties:
Instance – gives you that ability to access all the properties of the section.
Setting – key value collection, well you can guess what it does.

Now you can write code like this:

TestSection.Instance.Prop1;
TestSection.Settings["first"];

Not bad I think for folowing allmost the same steps of creating a configuration section. But wait there is more (I promised in 3rd point int our goads definition). Now let me take you one stap foraord. Let's say I have tree environments in my work, dev, test and prod. All three of them have common setting like whether to write a log or not, but also they have uniqe data like user name and password. I want to be able to handle all this in one simple configuration section.

Let see the solution - class definition:

public abstract class ConfigurationMuiltiSectionBase<CurrentClass, ConfigurationCollectionElementClass> : ConfigurationSectionBase<CurrentClass>
where CurrentClass : ConfigurationMuiltiSectionBase<CurrentClass, ConfigurationCollectionElementClass>

where ConfigurationCollectionElementClass : ConfigurationSingleSectionBase<ConfigurationCollectionElementClass>
that would be our multi section class. As you can see the generic class gets the derived class itself as it type and another class of type ConfigurationSingleSectionBase.

Now you can define something like this:

[ConfigurationSection("projectenv")]
public class ProjectEnv : ConfigurationSingleSectionBase<ProjectEnv>
{
    private const string Prop1Name = "Name";
    [ConfigurationProperty(Prop1Name)]
    public string Name
    {
        get { return GetSectionValue<string>(Prop1Name); }
    }

    private const string Prop2Name = "User";
    [ConfigurationProperty(Prop2Name)]
    public string User
    {
        get { return GetSectionValue<string>(Prop2Name); }
    }

    private const string Prop3Name = "Password";
    [ConfigurationProperty(Prop3Name)]
    public string Password
    {
        get { return GetSectionValue<string>(Prop3Name); }
    }
}

[ConfigurationSection("environments")]
public class Environments : ConfigurationMuiltiSectionBase<Environments, ProjectEnv>
{
    private const string Prop1Name = "IsWriteConfig";
    [ConfigurationProperty(Prop1Name)]
    public bool IsWriteConfig
    {
        get { return GetSectionValue<bool>(Prop1Name); }
    }

    private const string Prop2Name = "ActiveSystem";
    [ConfigurationProperty(Prop2Name)]
    public int ActiveSystem
    {
        get { return GetSectionValue<int>(Prop2Name); }
    }
} 

And add the following definition to the config file:

Now you we write

Environments.Settings[0].Name;

or

Environments.Settings[Environments.Instance.ActiveSystem].Name;

as you can see

The return type of our setting is now a list of our inner section.

That’s it. Here is the code. Play with it a little and let me know if you find it usably.

Posted by Nati Dobkin | with no comments
תגים:

Scott Guthrie wrote a very nice visualizer for LINQ to SQL for easier debugging. Take a look on it and think maybe you can add something alike in your LINQ implementations.

 

I was looking for an ability to run automated tests from MSBuild, my demands are:

1) Be able to run tests from many solutions (that contains many projects and many tests).

2) Be able to control the entire test running definition from one file(and not to open each proj file to add a new test every time someone in my team writes one).

3) Be able to separate sets of tests that take more time to run from those that run with no time – usually it will be divided into unit and integration tests.

4) Do all this without using .vsmdi file – because from some reason this file not work properly within TFS source safe, which me and my team are using.

MSBuild have no task for running units. Those are the alternatives I found for units to run from MSBuild.

1) Run the MSTest command directly,by using exec task, like this

<Exec Command='"C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\mstest.exe" /testcontainer:c:\projects\MyTests\Sampe.Tests.dll />

This solution is pretty good if you have one test project to run, if you have more than one you have to specify the "/testcontainer:…" parameter for every project that you want to run. Or add new exec task.

If you have to run it for, let say five solutions, when each one contains more the one test project, you have already ten projects that you have to maintain, and I don’t want to be the one that doing this.

2) Running TestToolsTask task which comes with TFS and can be found in Microsoft.TeamFoundation.Build.targets file.

This one can be used only with .vsmdi files, and this differing number four in my demands.

3) Writing task of my own, and make all my dreams come true. And this is what I did.

The task has all the functionality that MSTest command line tool has.

How to use the task?

Import the task in you .proj file:

<UsingTask TaskName="Dobkin.Common.Tasks.MSTest"AssemblyFile="D:\MyFolder\Dobkin.Common.Tasks.dll"/>

And call the task:

<ItemGroup Condition="$(ProjectName) == 'Project1'">

        <Tests Include="c:\Project1\Project1.BL.Test.dll"/>

        <Test Include="c:\Project1\Project1.Dal.Tests.dll"/>

</ItemGroup>

 <ItemGroup Condition="$(ProjectName) == 'Project2'">

        <Tests Include="c:\Project2\Project2.BL.Test.dll"/>

        <Test Include="c:\Project2\Project2.Dal.Tests.dll"/>

        <Test Include="c:\Project2\Project2.Utils.Tests.dll"/>

</ItemGroup>

And that’s it. For now on, every new test project or even a whole new solution, you will add, you have to change only this file (for new solution of course you have to import this file first)

Documentation of how to use the task is included in the attachment.

MSTest.rar

When you first time run your WCF service (http://localhost/myCoolService.svc) you get a nice tutorial, made by Microsoft, that explain you how you should use the service. This is not hard to notice that you should close every connection you made to a service. Like this:

MyServiceClient client = new MyServiceClient();
client.Close();

I am using a lot of services in my apps and I don’t want to kip in mind that all the time I am using a service instance I have to remember to close the connection. So I wrote a simple code that handles the closing for me.

public class ServicesFactory : IDisposable
{
    List<object> services;

    public ServicesFactory()
    {
        services = new List<object>();
    }

    public T CreateService<T>() where T : ICommunicationObject
    {
        T service = Activator.CreateInstance<T>();
        services.Add(service);
        return service;
    }

    #region IDisposable Members

    public void Dispose()
    {
        foreach (object obj in services)
        {
            ICommunicationObject currService = (ICommunicationObject)obj;
            if (currService.State != CommunicationState.Closed)
                currService.Close();
        }

    }

    #endregion
}

Now every time I will create a service instance I will do it this way.

using (ServicesFactory factory = new ServicesFactory())
{
    WCFServiceEx.Client.Calculate.CalculateClient client = 
                            factory.CreateService<WCFServiceEx.Client.Calculate.CalculateClient>();

    // do service logic.
}

That will make shore that the connection of all the instances that I made in the scope will be closed as soon as the code in the scope will finished.

Posted by Nati Dobkin | with no comments

 

WCF provides nice capability of extending the behavior of operations by implementing IOperationBehavior interface. I want to concentrate on ApplyDispatchBehavior method of that interface, which purpose is to do extention to server side calls. I will show how I use this extensability to provide a nice and easy cache mechanisam.

I will make a class which derives from Attribute class and implements an IOperationBehavior interface. Now I want to interfire in the invoke process of the method so I need to make another class that implements IOperationInvoker interface and would hold the cache logic. And then set it to dispatch.Invoker property of the ApplyDispatchBehavior method. Let see some code:

class CacheMeAttribute: Attribute, IOperationBehavior
{
    #region IOperationBehavior Members
    public void ApplyDispatchBehavior(OperationDescription description, DispatchOperation dispatch)
    {
        dispatch.Invoker = new CommonInvoker(dispatch.Invoker);
    }
    //other interface methods.
    
    #endregion
} 
class CommonInvoker : IOperationInvoker
{
    public Cache AppCache
    {
        get
        {
            return HttpRuntime.Cache; 
        }
    }

    IOperationInvoker BaseInvoker;
        
    public CommonInvoker(IOperationInvoker baseInvoker)
    {
        this.BaseInvoker = baseInvoker;
    }
        
    
    #region IOperationInvoker Members

    public object[] AllocateInputs()
    {
        object[] ret = this.BaseInvoker.AllocateInputs();
        return ret;
    }

    public object Invoke(object instance, object[] inputs, out object[] outputs)
    {
        string key = GetCacheKey(inputs);
        object result = AppCache[key];
        if (result == null)
        {
            result = this.BaseInvoker.Invoke(instance, inputs, out outputs);
            AppCache[key] = result;
        }
        outputs = new object[0];
        return result;
     }

     // other interface methods.

      #endregion

    private string GetCacheKey(object[] inputs)
    {
        string key = string.Empty;
        for (int i = 0; i < inputs.Length; i++)
             key += inputs[0].ToString();
        return key;
    }
}

The cache algorithm is shown in the Invoke method and cache the return value of the calling method by the parameters given to the method input. I use HttpRuntime.Cache for the caching and it work well for both win and web application as I explained in my last post.

Now all you have to do in order to cache data is add CacheMe attribute over a method like this:

[ServiceContract(Namespace = "Dobkin.Services")]
interface IMyService
{
    [OperationContract]
    string Mult(int x, int y);
}

class MyService : IMyService
{
    [CacheMe]
    public long Mult(int x, int y)
    {
        return x * y;
    }
} 

And that's it. Now every time that Mult method will be called then the CommonInvoker will check if there is entry in the cache with a 'xy' key. If there is, the value will be returned to the caller without executing the method.

See full example of the code here.

Posted by Nati Dobkin | 3 comment(s)
תגים:,

 

Asp.Net provides us very powerful cache mechanism that can be found under System.Web.Caching. You can access the cache using the folioing syntax:

HttpContext.Current.Cache["key"] = value;

HttpContext.Current.Cache.Add(params...);

Lately I was looking for similar mechanism to use with WCF. The flax ability of WCF services provide them to live in supported as well not supported web environment. In that case HttpContext.Current would not be available. From curiosity I went and check how the HttpContext.Current.Cache property is implemented and I was surprised to see the all it does is: return HttpRuntime.Cache. After googling I was more suprized to find out that inspite it very weby name (you know Http…) it is not have to live in web supported envirment. The only check that made by this getter is 'if ASPNet is installed on the machine' and as far as I know it come with the installation of FrameWork.

The only explanation that I can see for this one is that the Cache class is places in not appropriate namespace.

So there is no matter how you will host you WCF service, within IIS (web app) or console app, you can use the cache mechanism by accessing HttpRuntime.Cache.

Some of you may say: "wait a minute, I am writhing a console application, why the hell do I need a reference to System.Web?" and I will agree that usually you don’t. But till Microsoft will come up with some appropriate solution for caching in client apps, I think this deviation from the common sense worth it.

 

There are some references on the issue:

http://www.hanselman.com/blog/UsingTheASPNETCacheOutsideOfASPNET.aspx

http://weblogs.asp.net/pjohnson/archive/2006/02/06/437559.aspx

Posted by Nati Dobkin | 1 comment(s)
תגים:,

 

Recently I been refactoring some legasy code and writing a new one. I am using Rhino mocks to run my units and for that I have to write my code in a testable way. This approach makes my code looks not exactly the way I designed and want it to be. Eli Lopian wrote an article about this issue – "Stop Designing for Testability" and has some points to think of.

In my opinion, if we have to write very simple code to encapsulate some internal logic for our base class and make sure that there is no way some smart ass will override it, but still give an opportunity to reuse this code in the deriving class, like this:

public abstract class MyBase
{
    protected void DoSomeVeryImportentLogicThatCanotBeOverriden()
    {
        DoTheSameVeryImportentLogic();
    }

    internal virtual void DoTheSameVeryImportentLogic()
    {
        // logic goes there.
    }
}

Only to make the code testeble – we are missing something – this is not the way code should look like.

There is also the impact on performance of making all our methods as virtual, to be able to override them when we make out mock classes, I agree with Roy Osherove one this on and we are not dealing here with real-time applications so the impact of the vtable that created when we are performing polymorphism (you can read about it from Shimon's post) is not so painful. And as Roy explained in his post if this is your pain in the ass you can deal with it.

I don’t really like the idea of losing the concept of OOP and clear and simple code writing over testable code.

What do you think?

Posted by Nati Dobkin | 3 comment(s)
תגים:

 

In the past few days I been dealing with setting up continues integration (CI) process in my team. The process is not finished yet but be ready for a post at the minute when it will be done.

CI is dealing with automated builds so I needed some automated build tool to handle the job. No so long ago I have been working with MSBuild, which is very powerful tool to manage your build process. However lately more and more often I run in to TFSBuild (which is a tool for automated build that come with TFS) relative with CI. I have seen tutorials about the tool and it seemed pretty simple. More over it has been written that this tool is based on MSBuild, and MSBuild we familiar with, so what can go wrong?! – In fact many things.

I have followed the guide lines and with a help of the tutorial I have made a new build type which included getting latest from the TFS source safe into my working directory, building the solution, running the unit tests and running the code analysis. So fare so well.

After a while I want to add some more tests to my build, which is a common task that every team member has to do at least once a week. Then I realized that there is no easy way to do that, the guide line said – "go to the safe source, check out of the build file, and then change the tests list hard coded" - why someone in my team have to care that there is some kind of build file!? But I said ok, let see where it goes. I have opened the build file and saw this task:

<IncludeDataFile Include="$(SolutionRoot)\MyProject\TestProject.vsmdi">
    <TestList>MyDalTest</TestList>
</IncludeDataFile>

When MyDalTest has to be a test list, which is a concept of VS 2005 for testers and not included in common VS 2005. Moreover I don’t want that for every test that someone of my teammate writes, he has to remember to add it to some kind of not understandable test list, and if some one will, one sunny day, forget to do this the test will never run at the CI process. I said "this is not the working process that I been looking for" and went to look for some alternatives. But before this I had to find out how Microsoft runs their test. So I go to the IDE folder in VS root installation folder, where I know Microsoft keep all their goodies, and I have found a command line tool that called MSTest.exe (you can find help about it here). I was surprised to see that this tool has very powerful ability to run tests in any form I only wish to, form running separate test to running .vsmdi files and entire solutions.

So as I see it Microsoft was able to make a very powerful tool to run their tests but someway hasn’t included it all features in their build process.

This disability of the team build running test and some other little thing that I had problem with made me to move to some better and more important more flexible alternatives like cruise control .net and standard MSBuild files

 

After my trip to Thailand Last month (see some photos) I back and jumped right in to coding. I wrote some code at work and tried to fix some unit tests for it using Rhino Mocks. I guess you all familiar with that powerful tool and I will not try to explain how to use it, it been done perfectly by some of my colleagues.

I wrote a class like this:

public class User 
{ 
  private void DoSomeLogic() 
  { } 

  public void Add() 
  { 
    DoSomeLogic(); 
    // ... 
  }
} 
When I came up to write the test I realized that the DoSomeLogic method, which I want to do some mocking and inject custom logic when I about to check the Add method, is not accessible from outside the class. So as good student I go and did what is written to do in such situation and make the DoSomeLogic method internal virtual and of course added:

[assembly: InternalsVisibleTo("MyAssembly.Test")]

To assemblyInfo file.

After that I managed to access this method and wrote test that looked like this one:

[TestMethod] 
public void Add_LogicFlow_Ok() 
{ 
  Rhino.Mocks.MockRepository mocker = new MockRepository(); 
  User user = mocker.CreateMock<User>(); 
  using (mocker.Record()) 
  { 
    user.DoSomeLogic(); 
  } 
} 

And my class, after the change, looked like this:

public class User 
{ 
  internal virtual void DoSomeLogic() 
  { } 

  public void AddUser() 
  { 
    DoSomeLogic(); 
    // ... 
  } 
} 

I run the test, with hope that it will pass. But, as you know, the life is no so simple and I got an exception that look very strange because it looked like it came from my original DoSomeLogic method - isn’t the user instance is a mock?!

Before I manage to say "WTF", which is very sort acronym, I was on debug mode to see what is going on. And in fact the user.DoSomeLogic(); - which is inside my record statement, went directly to my original User.DoSomeLogic() – what is definitely not what I meant to do.

I try digging and se what is wrong. After a while and with help of yoav we came up with conclusion that Rhino can not access this method (because it internal) and cannot override it when it mocking my class.

A solution to this problem can be made by two ways.

1. add protected to the definition of the method like this:

public class User 
{ 
  protected internal virtual void DoSomeLogic() 
  { } 

  public void AddUser() 
  { 
    DoSomeLogic(); 
    // ... 
  } 
} 

2. add [assembly: InternalsVisibleTo("Rhino.Mocks")]

The first solution is missing some basic purpose of what I have intended to do, because in such case you open an opportunity for deriving class to override logic (DoSomeLogic method ) which, as fare as you remember, was private at the beginning. This solution is useful only if the class itself is internal. In that case you anyway need to go to second solution, in order to Rhino could see the class and mock it. So this is what I did. I add the necessary line in to assemblyInfo and added to it the public key of the Rhino assembly (which I get by running command line - "sn –Tp Rhino.mocks.dll") something simple like this:

[assembly: InternalsVisibleTo("Rhino.Mocks, PublicKey=00240000048000009400000006020000002400005253413100040000010001009D1CF4B75B7218B141AC64C15450141B1E5F41F6A302AC717AB9761FA6AE2C3EE0C354C22D0A60AC59DE41FA285D572E7CF33C320AA7FF877E2B7DA1792FCC6AA4EB0B4D8294A2F74CB14D03FB9B091F751D6DC49E626D74601692C99EAB7718ED76A40C36D39AF842BE378B677E6E4EAE973F643D7065241AD86ECC156D81AB")]

Unfortunately it hasn't helped. I still was unable to make a mock of my user type. As you can figure the same problem will appear testing a internal classes.

After hitting some values at Google I figured that Rhino come with very helpful constant - Rhino.Mocks.RhinoMocks.StrongName which holds the assembly name and public key (which apparently is different from the one that I have found). So after I add this line

[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]

My user type could be mocked and the test finally passed!

In my last code review, which has made by shani raba, he have write me down a comment about the way that I read data from XML file, which is with the help of XmlDocument. And his point was that that way it is much slower then with, lets say, XmlReader.

So I have googled and came up with those conclusions. Using a XmlDocument for reading XML files is really a bit slower then using XmlRaeder. Although if you need also to write into the XML this would be the prepared option.

The XmlReader work 2-3 times faster then the XmlDocument because it doesn't save state of the document and the pointer on then file can be moved only forward. I say keep that idea aside for rainy day when you have to work with 10M XML files with thousands of elements. For now if you need to handle much smaller XML files then I suggest to use XmlDocument, even if you want only to read data. The overhead is negligible and only think about the benefits that you get. You have one object, which by my opinion is really easy to use, that can handle what ever you think of with XML files. And more importantly you keep on really strict standard for all your code. I think this is worth the price that you pay doesn’t it?

So I recommend using XmlDocument for managing your XML files in 90% of the time.

There are more objects that you can use to handle XML files.

You can find here some comparing between all of them.

More Posts Next page »