Multiple usings bundled

Interesting thing to note. While you can bundle multiple using together by nesting as shown in example 1, you can totally avoid the nesting by removing some braces and still have the same effect as shown in example 2. You may expect that the first object will immediately be disposed before the next line executes but this is syntactic sugar to work as the first example.

Example 1:


            using (var a = new Test())
            {
                using (var b = new Test())
                {

                }
            }

Example 2:


            using (var a = new Test())
            using (var b = new Test())
            {

            }

 

Make custom types support object initializers

In C# you can easily make your custom types support object initializers by doing two things

  • Implement IEnumerable<T>
  • Add a public void method called Add accepting the type desired intializer type as a parameter

Example:

Implement IEnumerable<T>


    public class ProgrammingLanguage:IEnumerable&lt;string&gt;
    {
        private readonly HashSet&lt;string&gt; supportedTypes = new HashSet&lt;string&gt;();

        public IEnumerator&lt;string&gt; GetEnumerator()
        {
            return this.supportedTypes.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }
    }

Add the Add method


        public void Add(string name)
        {

        }

Sample usage:


            var javaScript = new ProgrammingLanguage{&quot;int&quot;,&quot;bool&quot;,&quot;string&quot;};

Update:

Interestingly for an object to be enumerable and say qualify to be iterated by foreach it does not have implement IEnumerable. Instead it simply has to have a public method GetEnumerator that returns a type with a public bool MoveNext and public void Current. The compiler does not actually check to see if the interface is implemented.

Frustration with System.IO.Packaging.Package

I have had a very frustrating time with making use of Packages to zip files in .NET. Below is a question I posted on stackoverflow together with the hack I used to make it go away fast.

I am making use of the System.IO.Packagng.Package class to zip files. It is possible to have multiple instances of my application running at the same time with files being read and saved. When working with small files all seems fine, however when large files are involved if two instances of the application save at the same time I get an exception with the message Store must be open for this operation with the stack trace shown below.

From my understanding when working with the packages for files <10mb the data is stored in some memory stream but when it is >10mb internally that will switch to IsolatedStorage. With that in mind I was able to find that even though these are multiple instances running they all get the same isolated storage location resolved and I believe that is were the problem comes in. I was able to find a hack to force each instance to resolve to a different location using the following code:


            var s_DirUserField = typeof(IsolatedStorageFile).GetField("s_RootDirUser", BindingFlags.NonPublic | BindingFlags.Static);
            s_DirUserField.SetValue(null, @"&amp;lt;unique location in IsolatedStorage&amp;gt;");

Even though that made the problem go away I do not like it one bit. Please help in figuring out how to fix this problem elegantly. On further research I found out that IsolatedStorage is not even meant to be used with multiple threads, which gets me to wonder why it was then an option when dealing with Packages.

   at System.IO.IsolatedStorage.IsolatedStorageFileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, IsolatedStorageFile isf)
   at MS.Internal.IO.Packaging.PackagingUtilities.SafeIsolatedStorageFileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, ReliableIsolatedStorageFileFolder folder)
   at MS.Internal.IO.Packaging.PackagingUtilities.CreateUserScopedIsolatedStorageFileStreamWithRandomName(Int32 retryCount, String& fileName)
   at MS.Internal.IO.Packaging.SparseMemoryStream.EnsureIsolatedStoreStream()
   at MS.Internal.IO.Packaging.SparseMemoryStream.SwitchModeIfNecessary()
   at MS.Internal.IO.Packaging.SparseMemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count)
   at MS.Internal.IO.Zip.ZipIOFileItemStream.Write(Byte[] buffer, Int32 offset, Int32 count)
   at MS.Internal.IO.Zip.ProgressiveCrcCalculatingStream.Write(Byte[] buffer, Int32 offset, Int32 count)
   at MS.Internal.IO.Zip.ZipIOModeEnforcingStream.Write(Byte[] buffer, Int32 offset Int32 count)

Update:

Additionally one can experience issue because to access IsolatedStorage your code must have all the necessary native platform operating system rights and if it doesn’t it will fail to create an IsolatedStorage stream.

The decision to make use of Isolated Storage here was not a very good and one another developer Eric White was kind enough to rewrite System.IO.Packaging to not use Isolated Storage and his rewrite will be part of COREFX.

Update 2

A hotfix for the .NET Framework 4.5, 4.5.1, and 4.5.2 on Windows 8.1 and Windows Server 2012 R2 was released addressing this issue. In my case this does not help as I am stuck with .NET 3.5 for the given applciation.

Other problem indicated by Microsoft that could occur with System.IO.Packaging related to this are as follows.

A deadlock may occur when you use large packages on separate threads. System.IO.Packaging uses IsolatedStorage for packages that are larger than 10 megabytes (MB). When two or more threads use large packages, a deadlock may occur, even if the packages are independent. The deadlock involves two threads. One is waiting in IsolatedStorageFile.Lock while the other is waiting in another method of the IsoloatedStorageFile class. This issue is fixed by adding synchronization to System.IO.Packaging to avoid the problem in IsolatedStorageFile. Exceptions may occur when you retrieve PackageProperties from packages that are opened on separate threads, even if the packages are independent. The most common call stacks that arise from this are as follows:

System.Xml.XmlException: Unrecognized root element in Core Properties part. Line 2, position 2.     at
MS.Internal.IO.Packaging.PartBasedPackageProperties.ParseCorePropertyPart(PackagePart part)     at
System.IO.Packaging.Package.get_PackageProperties()
System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.  Parameter name: id     at
MS.Internal.IO.Packaging.PartBasedPackageProperties.ParseCorePropertyPart(PackagePart part)     at
System.IO.Packaging.Package.get_PackageProperties()

Git squash multiple commits into one

If you ever have a scenario where you have to make a lot of changes to a branch but commit regularly so you can go back during this process if something fails BUT when you are done as a whole none of those commits actually matter except the last one (historically it will be off no use to see what was changing between revisions) you can do this in git:

Note: Before you do this all your changes need to have been committed, make sure you have nothing staged.

git reset –soft <sha_of_initial_commit>
git commit -a –amend -m “commit message”

Update to Undisposed.Fody

In my previous post I talked about Undisposed.Fody which has proven useful to me before in a live project. One problem I had however on using it was that I could see an undisposed object at a stage when I know it should have been disposed and flag this. The problem however was to know for sure who created the object as there could potentially be many branches in my code that could instantiate that dude.

To help myself I went and forked the gihub repo for Undisposed.Fody and added an option to dump the creation stacktrace on dumping undisposed objects. You can find my fork here. I have made a pull request and hope it will be added to the main repo.

Tracking undisposed items with Undisposed.Fody

I have recently had to do a little cleanup and ensure that there are no heavy objects that don’t get disposed. To do this I made use of my trusty friend Fody and the addin Undisposed.Fody.

Undisposed.Fody is a Fody addin and a standalone application that helps to track down undisposed objects. Occasionally crashes or application hangs are caused by undisposed objects, especially if the objects references COM objects.

This tool injects some code in all classes that implement IDisposable. It registers the creation of such objects and dumps the undisposed objects together with object creation counter. This helps to set a breakpoint in the constructor and break on the n-th call, thus making it possible to see where the object got created (and not disposed later on)

https://github.com/ermshiperete/undisposed-fody

Below is a sample with comments that illustrates how this fody addin works.

Classes we will be tracking objects for disposal:


    public class  Sample2:Sample
    {
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                //dispose managed resources
            }
            //dispose unmanaged resources
            this.isDisposed = true;
        }
    }

    public class Sample : IDisposable
    {
        protected bool isDisposed;

        public void Dispose()
        {
            this.Dispose(true);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                //dispose managed resources
            }
            //dispose unmanaged resources
            this.isDisposed = true;
        }
    }

When using Fody (simply add Undisposed.Fody nuget reference) it will inject code on compilation. The sample classes above will be compile as follows (using Telerik JustDecompile to observer after build):


    public class Sample : IDisposable
    {
        protected bool isDisposed;

        public Sample()
        {
            DisposeTracker.Register(this);
        }

        public void Dispose()
        {
            DisposeTracker.Unregister(this);
            this.Dispose(true);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
            }
            this.isDisposed = true;
        }
    }

Next we set the DisposeTracker.OutputKind to Dump for verbositey and add a delegate to print to debug as the DisposeTracker.LogWriter Action. On dumping undisposed objects before initializing anything the dump is empty, after calling Test we can see that we have one undisposed object.


        static void Main(string[] args)
        {
            DisposeTracker.OutputKind = TrackerOutputKind.Dump;
            DisposeTracker.LogWriter = delegate(string s) { Debug.WriteLine(s); };
            DisposeTracker.DumpUndisposedObjects();
            Test();
            //at this point both variables created in test should be out of scope and disposed
            //Fody will show b - Sample2 as undisposed which will be a red flag, we can then go and fix it
            DisposeTracker.DumpUndisposedObjects();
        }

Output:

**** Undisposed Object Dump:
**** Undisposed Object Dump:
Fody.Undisposed_Recipe.Sample2: 1

INotifyPropertyChanged Extensions

I have below simple extension methods you may find handy in raising the notifypropertychanged event, particularly if you are not using any MVVM framework.


   public static class PropertyChangedEventExtensions
   {
       public static void Raise(this PropertyChangedEventHandler propertyChangedEventHandler, object sender, [CallerMemberName]string propertyName = null)
       {
           var handler = propertyChangedEventHandler;
           if (handler != null)
           {
               handler(sender, new PropertyChangedEventArgs(propertyName));
           }
       }

       public static void Raise(this PropertyChangedEventHandler propertyChangedEventHandler, object sender, params string[] propertyNames)
       {
           var handler = propertyChangedEventHandler;
           if (handler != null)
           {
               foreach (string propertyName in propertyNames)
               {
                   handler(sender, new PropertyChangedEventArgs(propertyName));
               }
           }
       }
   }

And sample usage:


    public class Sample:INotifyPropertyChanged
    {
        private string testProperty;

        public string TestProperty
        {
            get { return this.testProperty; }
            set
            {
                this.testProperty = value;
                this.PropertyChanged.Raise(this);
            }
        }

        private void BulkNotifyPropertyChanged()
        {
            this.PropertyChanged.Raise(this,"A","B","C");
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }

Know your collection of collections

One of the things I have always find to be easily ignored by developers, in some cases even seniors is a good understanding of collecttions available in .NET, how they differ and when to apply which. That is before we even talk about more complex collections that you would not use for common scenarios. It is very important to always apply the right collection to any given requirement. As a basic I think one should be aware of the general collections that are available in .NET. I have compiled an exhaustive list below. I will not provide detail about these collections as I feel it is easy accessible information from other resources such as MSDN.

  • System.Collections.ObjectModel.ReadOnlyObservableCollection<T>
  • System.Collections.ObjectModel.ReadOnlyDictionary<T>
  • System.Collections.ObjectModel.ReadOnlyCollection<T>
  • System.Collections.ObjectModel.ObservableCollection<T>
  • System.Collections.ObjectModel.KeyedCollection<T>
  • System.Collections.ObjectModel.Collection<T>
  • System.Collections.Stack
  • System.Collections.SortedList
  • System.Collections.Queue
  • System.Collections.Hashtable
  • System.Collections.BitArray
  • System.Collections.ArrayList
  • System.Collections.Concurrent.BlockingCollection<T>
  • System.Collections.Concurrent.ConcurrentBag<T>
  • System.Collections.Concurrent.ConcurrentDictionary<T>
  • System.Collections.Concurrent.ConcurrentQueue<T>
  • System.Collections.Concurrent.ConcurrentStack<T>
  • System.Collections.Concurrent.OrderablePartitioner<T>
  • System.Collections.Concurrent.Partitioner
  • System.Collections.Concurrent.Partitioner<T>
  • System.Collections.Specialized.HybridDictionary
  • System.Collections.Specialized.ListDictionary
  • System.Collections.Specialized.NameValueCollection
  • System.Collections.Specialized.OrderedDictionary
  • System.Collections.Specialized.StringCollection
  • System.Collections.Specialized.StringDictionary
  • System.Collections.Generic.Dictionary<T>
  • System.Collections.Generic.HashSet<T>
  • System.Collections.Generic.LinkedList<T>
  • System.Collections.Generic.List<T>
  • System.Collections.Generic.Queue<T>
  • System.Collections.Generic.SortedDictionary<T>
  • System.Collections.Generic.SortedList<T>
  • System.Collections.Generic.SortedSet<T>
  • System.Collections.Generic.Stack<T>

DeploymentItemAttribute for NUnit

In a previous post I talked about the proper use of the DeploymentItemAttribute when running MSTests. If you do move to NUnit and have gotten used to depending on this attribute then worry not, I have you covered. Below I have code samples showing the custom attribute I have created to imitate the MSTest behaviour and usage samples. A good scenario of when you might want to use this is when you have a resource used by multiple tests and can be modified by any of the tests, in which case you want each test to have its own fresh copy.


    public class SampleTest : TestBase
    {
        [DeploymentItemAttribute(@"resources\file.txt", "TestName")]
        [Test]
        public void TestName()
        {
        }
    }

    public class TestBase
    {
        [SetUp]
        public void Setup()
        {
            this.DeployItems();
        }

        private void DeployItems()
        {
            var currentType = this.GetType();
            var publicMethodsWithTestAttr = currentType.GetMethods(BindingFlags.Instance | BindingFlags.Public)
                .Where(x => x.CustomAttributes.Any(y=>y.AttributeType == typeof(TestAttribute)));

            //Iterate through each test method and deploy files as necessary
            foreach (MethodInfo testMethodInfo in publicMethodsWithTestAttr)
            {
                var deploymentItemAttrs = testMethodInfo.GetCustomAttributes(typeof(DeploymentItemAttribute));
                foreach (DeploymentItemAttribute deploymentItemAttr in deploymentItemAttrs)
                {
                    this.DeployFile(deploymentItemAttr.Path,deploymentItemAttr.OutputDirectory);
                }
            }
        }

        private void DeployFile(string path, string outputDirectory = null)
        {
            string filePath = path.Replace("/", "\\");

            string originalItemPath = new Uri(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), filePath)).LocalPath;
            string originalItemName = Path.GetFileName(originalItemPath);

            string runFolderPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

            Debug.WriteLine("DeploymentItem: Copying " + originalItemPath + " to " + runFolderPath);

            string itemPathInBin;
            if (string.IsNullOrEmpty(outputDirectory))
            {
                itemPathInBin = new Uri(Path.Combine(runFolderPath, originalItemName)).LocalPath;
            }
            else if (!string.IsNullOrEmpty(Path.GetPathRoot(outputDirectory)))
            {
                itemPathInBin = new Uri(Path.Combine(outputDirectory, originalItemName)).LocalPath;
            }
            else
            {
                itemPathInBin = new Uri(Path.Combine(runFolderPath, outputDirectory, originalItemName)).LocalPath;
            }

            if (File.Exists(originalItemPath)) // It's a file
            {
                string parentFolderPathInBin = new DirectoryInfo(itemPathInBin).Parent.FullName;

                if (!Directory.Exists(parentFolderPathInBin))
                {
                    Directory.CreateDirectory(parentFolderPathInBin);
                }

                File.Copy(originalItemPath, itemPathInBin, true);

                FileAttributes fileAttributes = File.GetAttributes(itemPathInBin);
                if ((fileAttributes & FileAttributes.ReadOnly) != 0)
                {
                    File.SetAttributes(itemPathInBin, fileAttributes & ~FileAttributes.ReadOnly);
                }
            }
            else if (Directory.Exists(originalItemPath)) // It's a folder
            {
                if (Directory.Exists(itemPathInBin))
                {
                    Directory.Delete(itemPathInBin, true);
                }

                Directory.CreateDirectory(itemPathInBin);

                foreach (string dirPath in Directory.GetDirectories(originalItemPath, "*", SearchOption.AllDirectories))
                {
                    Directory.CreateDirectory(dirPath.Replace(originalItemPath, itemPathInBin));
                }

                foreach (string sourcePath in Directory.GetFiles(originalItemPath, "*.*", SearchOption.AllDirectories))
                {
                    string destinationPath = sourcePath.Replace(originalItemPath, itemPathInBin);
                    File.Copy(sourcePath, destinationPath, true);

                    FileAttributes fileAttributes = File.GetAttributes(destinationPath);
                    if ((fileAttributes & FileAttributes.ReadOnly) != 0)
                    {
                        File.SetAttributes(destinationPath, fileAttributes & ~FileAttributes.ReadOnly);
                    }
                }
            }
            else
            {
                Debug.WriteLine("Warning: Deployment item does not exist - \"" + originalItemPath + "\"");
            }
        }
    }

    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = true, Inherited = false)]
    public class DeploymentItemAttribute : Attribute
    {
        public DeploymentItemAttribute(string path, string outputDirectory = null)
        {
            this.Path = path;
            this.OutputDirectory = outputDirectory;
        }

        public string Path { get; set; }

        public string OutputDirectory { get; set; }
    }