Debugging “composition produced multiple composition errors”

by Billkrat 22. November 2014 04:40

 Programming with Prism using MEF as an IOC container is very powerful but it can generate some intimidating error messages.  During a minor refactor where I had moved module tracking components out of its own project into a more global MEF infrastructure project I received the following compile error that indicated I now had 8 root causes to numerous composition errors – the only clue I was going to be given was that there were duplicate exports…. 

001-Error

The cause was quickly found by stepping through ConfigureAggregateCatalog() method while viewing its Parts property and observing the parts listed after each AssemblyCatalog is added.  In this case I found the problem early in the process within a baseclass that loaded the MefInfrastructure project.   Before the refactor I was referencing the CallbackLogger in MefInfrastructure and the ModuleTracker in a separate assembly – now that I had moved the ModuleTracking code into MefInfrastructure I was effectively loading each of its Parts twice!

002-Cause

After removing the offending code I was back in business :)

004-Working

ToolBarTray - Programmatically adding ToolBars (Prism/MEF)

by billkrat 14. November 2014 07:31

Source Code: PrismMefPocV2.zip (4 meg)

It is surprisingly hard to find any references on how to programmatically add ToolBars to the WPF ToolBarTray control – as a matter of fact, I never found an example!  Not in any books on Safari Books Online nor researching the internet; everything demonstrates how to do it from XAML alone.   The problem with this is that I have a reusable View and ViewModel sitting in an external project (MefInfrastructure, ref figure 2) that I can’t hardcode XML ToolBars into if I hope to reuse them with other Windows – it has to be done programmatically.

Since I’m using Prism, with MEF as the IOC container, I need to first create a toolBarCollection (ref line 87 in figure 1) and then insert the instance into my MEF container (the next line).  

As for the button clicks, on lines 83-84 of figure 1, I am handling all button clicks for this ToolBarTray with the button_Click() method on line 91 – it will simply open a message box displaying the content of the button for this phase of POC development.  UPDATED:  button click in source code now loads module, ref figure 3.

Note: for those of you not using Prism/MEF – examine the code underlined in yellow in figure 2 to see how to take the collection on line 87 of figure 1 and programmatically add it to the ToolBarTray.

002-Source
Figure 1

With the ObservableCollection<ToolBar> instance exported, I can now easily import it into any applicable class, e.g., in this POC I am importing the values into the ToolBarViewModel (ref figure 2 below on line 11 in the top right pane).

So anytime I import the ToolBarViewModel, as I do on line 21 in figure 1, the ToolBarCollection property of the ToolBarViewModel will be automagically populated with the instance stored above.

With the ViewModel now populated with the ToolBar collection to be utilized by the view, it is now time to attach the ViewModel to its View, this is done on line 43 in figure 1 (above).  The magic happens in the ToolbarView code-behind (reference code underlined in yellow below) within the constructor.   When the DataContext changes it will take the contents of the ToolBarViewModel.ToolBarCollection and programmatically add each ToolBar to the ToolBarTray (x:Name=CtrlToolBarTray).

This permits all of the components in the MefInfrastructure project to remain completely decoupled, neither the ToolbarView nor ToolBarViewModel have any dependencies of external components.

001-Decoupled
Figure 2

UPDATED:  Source code updated to launch modules B, C, and F upon applicable button click.  All of these modules are configured to load “on demand” so they are not automatically loaded – line 83 in figure 3 loads the module.

003-Updated
Figure 3

Retrieve the LoaderExceptions property for more information

by billkrat 13. November 2014 12:20

Issue Reported: #10720

I’ve spent far more time than I care to admit chasing this error as it forced me to take a deep dive into the Prism/MEF source code.  Ironically, the error was caused by the process I used to trace errors in the first place – I had removed all reference to assemblies and was only using reference to Prism projects (source code).

During execution of my Prism/MEF POC, the ModuleManager class generated the error “Unable to load one or more of the requested types” and indicated that I should “Retrieve the LoaderExceptions property for more information”; it would be nice if the LoaderExceptions property in the default error window (reference highlighted below) would actually show them but it simply displays {System.Exceptions[1]} which started me on my new adventure…

002-LoaderExceptions

In reviewing the sequence diagram that I constructed earlier for Prism/MEF (available here) I found that I could trap the error for this phase of processing by overriding my AppBootstrapper.InitializeModules() method as shown in image below (lines 90-100).   This revealed the actual problem in ex.InnerException.LoaderExceptions[0] which was complaining that it “Could not load file or assembly Microsoft.Practices.Prism.Composition, Version=5.0.0.0…

003-TrapError

This seems like an easy enough solution but wouldn’t it be better if we didn’t have to know a lot when an error occurred?  I want this to be the case with my development platform, so I did the deep dive and found the applicable place to update the Prism for MEF source code so I could have the following (see “AFTER” block below):

001-ScreenShots

Now this error makes a lot of sense and is self explanatory!  At a glance I can see what my problem is.  In reviewing my module configuration, in the AppBootstrapper.ConfigureAggregateCatalog() below, I can see that ModuleA and ModuleD are referenced by the main project so I simply add them on lines 44-45 and I’m done.  ModuleE and ModuleF on the other hand are standalone modules that I reference via the app.config file (lines 7 and 12 in bottom pane of image below), these are programmatically loaded via the ModuleManager which is complaining about the ModuleE reference to Microsoft.Practices.Prism.Composition, Version 5.0.0.0 .  The problem is that ModuleE is referencing the Prism assemblies versus the Prism Projects as the other modules are referencing so MEF cannot load the assembly (the project assembly is already loaded).

004-Understandable

Once I removed the assembly references and referred to the actual Prism projects my issue went away and I was successfully loading modules A, D, and E as shown below. 

005-works

Note: the referenced modules correctly load after the “Initializing modules” logging statement because of the bug fix applied in this blog => MEF Extension Bug–unexpected module initialization

The exception handling fix that allows us to quickly see the LoaderExceptions is shown in the image below (enclosed in yellow rectangles) – it requires us to first cast to ReflectionTypeLoadException so that we can then access the LoaderExceptions (line 273).

006-final

MEF Extension Bug–unexpected module initialization

by billkrat 6. November 2014 08:08

While studying the Microsoft ModularityWithMef.Desktop sample (to see what P&P components I can borrow) I was perplexed by where/why/how modules were being constructed and initialized before the shell constructor was even being hit.  It was such a distraction that I had to stop my R&D so that I could pull out the signed assemblies, download the source, and plug the source projects into the their sample application to debug this unexpected behavior.

Bug reported HERE

001-BadLog
Figure 1

 

In reviewing the sequence diagram that I constructed earlier for Prism/MEF (available here) I saw no clues as to why this was happening – nothing in the Shell.xaml.cs file was performing a moduleManager.LoadModule() as it was doing for modules B, C, E, and F (on applicable widget click).

002-sequence
Figure 2

The problem stems from the MEF Import of IModuleManager in the Shell on line 24.   This import is used to get a reference to the module manager so that modules B, C, E, and F can be manually loaded and so that events can be subscribed to as shown in image below (yellow box).

005-StartsWith
Figure 3

The culprit is the highlighted line 93 in the image below.  Once the IModuleManager implementation is constructed, and its imports satisfied, the OnImportsSatisfied() method will fire which effectively loads the ModuleCatalog.Modules property with available information.  The problem is that after this processing is completed we are telling the MefModuleManager to LoadModulesThatAreReadyForLoad() which short circuits Prism logic by jumping the gun – this line should be remarked out (more below).

004-Culprit
Figure 4

Because both modules A and D are initialized with a state of ReadyForInitialization() they both will have InitializeModule() executed on them (highlighted below on line 195).

006-ReadyForInitialization
Figure 5

The above InitializeModules(moduleInfo) in turn will CreateModule(moduleInfo) and then Initialize() it, reference highlighted box in image below:

007-Initialized
Figure 6

If however, you remark out the LoadModulesThatAreReadyForLoad() in the MefModuleManager.OnImportsSatisfied() on line 93 in figure 4 then you will get expected behavior as shown below:

003-GoodLog
Figure 7

How to use MEF’s convention model in PRISM

by billkrat 4. November 2014 05:52

Sequence diagram: application bootstrapper.
Source Code: PrismMefPoc.zip

Being a long time fan of Unity IOC I was/am somewhat reluctant to move to MEF but am finding that it offers features that Unity does not, particularly the ability to easily import modules (add-ins) from a folder.  

One of the improvements to MEF in .NET 4.5 was the support of the convention based programming model.  It permits us to import and export with no attributes; we can simply declare the types.
Where their demo code for MEF convention models was simple enough to use, I was stumped on how to implement it within Prism as there are no examples within the Prism V5 package – it only shows how to perform attributed imports and exports. I’ve reached out to Microsoft and Prism community but in the absence of any feedback will have to roll up my sleeves and figure it out…

I started by creating two commands, the use case for this POC is that these commands need to be executed after all modules have been loaded in Prism.   Originally they where going to be POCO objects however I wanted to ensure that my commands, within the MefInfrastructure project, would have access to attributed imports.   So I added an IModuleManager import to DemoCommandA and a CallbackLogger attribute to DemoCommandB – if imports are successful there will be a smiley face after the module name when logged to the output window.

001-Commands

In the bottom left window of the image below we see the MefSample application running and that our DemoCommandA and DemoCommandB commands have been successfully imported and executed by our AppBootstrapper.

Note that neither the exports (above) and the import property Commands (line 18 below) have any attributes, we use the Registration Builder in the ConfigureAggregateCatalog() method to declare them programmatically (in yellow box below). 

002-Code

So the question to be answered was, where was the best place (for this particular use case) to handle the processing of these commands.   To figure this out I created a sequence diagram of the AppBootstrapper –> MefBootstrapper –> Bootstrapper as shown in the image below.   The last method to be called by the MefBootstrapper is InitializeModules, which loads the module manager and launches all modules.   I did an override of this method using the following code, it in turn will call ModulesInitialized() where my processing will occur:

        protected override void InitializeModules()
        {
            base.InitializeModules();
            ModulesInitialized();
        }

        private void ModulesInitialized()
        {
            Container.SatisfyImportsOnce(this, _conventions);

            foreach (var command in Commands)
            {
                if (command.CanExecute(this))
                    command.Execute(Logger);
            }
        }

003-Bootstrapper

Alternately, if my use case were that my commands needed to perform processing and add instances to the container for module use, I found that processing could be done in a more appropriate place within the ConfigureContainer() method (passing in the container as a parameter) using the following code:

        protected override void ConfigureContainer()
        {
            base.ConfigureContainer();
            this.Container.ComposeExportedValue<CallbackLogger>(this.callbackLogger);

            Container.SatisfyImportsOnce(this, _conventions);

            foreach (var command in Commands)
            {
                if (command.CanExecute(this))
                    command.Execute(container);
            }
        }
Reference sequence diagram below:
004-Alternate

Tags:

MEF | Prism

Windows 10 - nice… even fixed my Samsung Slate docking issue

by billkrat 1. October 2014 18:42

Want Windows 10? Go to => http://preview.windows.com
g8s9e0vsqiysarqvbqr5

I haven’t had such a seamless operating system installation since installing Windows Server 2012 R2 – it was a plug’n play!   I’m use to having a few head-bangers to work through…

I was very happy to see an upgrade feature for Windows 10, particularly since I had just finished reinstalling Windows 8.1 on my Samsung Slate (64 gig drive) along with Visual Studio Ultimate 2013 only to find my Slate docking station problem did not go away – I could not use the USB port on it (which was hooked up to a powered USB hub).  It seems others have the same issue with no solution – my issue happened after an automatic update and I’ve had to struggle without it for a few months.  It was great to see my hardware/docking station is fully functional after installing Windows 10.

So I was pleasantly surprised about many things. 

  1. First and foremost, a very cool start button/menu which has tile support and the look and feel of the Windows 7 start button. When you pin an application to start it appears in the Tile window which is part of the start menu.
    Start


  2. I was happy to see that I wasn’t going to have to spend an hour uninstalling applications so that I could do the update.  Typically I have to free up a minimum of 18 gig (Windows 8.1 installs) which means having to uninstall Visual Studio 2013 and Phone SDKs, since I’m usually scraping 13 gig this sometimes mean I have to uninstall other programs. 

    I was surprised that with only 13 gig available I was able to do the install, what surprised me more was that when the installation was completed I actually had more space than when I started.  Pretty impressive considering that I had almost 4 gig sitting in a new Windows.old folder; once I got rid of it I was going to have more space than I was accustomed to.Install


  3. I was pleasantly surprised to find I didn’t have to jump through hoops to delete the Windows.old folder.  Typically I change ownership of the folder (as I did this time) and will find that some folders can’t be deleted because the file names are too long.  This requires me to show all hidden files, drill down into the users folder, and cut/paste the folder to my root drive which doesn’t always work.   This time things were seamless - I simply deleted it and the folder was gone.

    Install02


  4. I was happy to see that my three monitors where readily available – one being a USB monitor (top monitor in image below) that requires the Display Link driver installed, my 25 inch HPw2558hc HDMI monitor (bottom left), and of course the Samsung Slate itself (bottom right).

    Screenshot



  5. I loved that the default environment was for a Windows 7 look and feel.  Wish my Windows 7 monitors (for work) all had their own taskbar which Windows 10 retained from Windows 8.1.   When I launched a WinRT application it loaded full-screen in my Slate which felt exactly like Windows 8.1 with charms and touch features – the main difference is that the taskbar and caption (with minimize, restore, and close icons) was available.  I could drag the WinRT applications to my other screens and even overlay it as a window as shown in the bottom left monitor (store app).

    The only thing that felt unnatural (I’ve been on Windows 8 since CTP) was that I could not access the charms via the mouse on non-touch screen monitors – none of the mouse support was available.   The slate worked as expected so I suspect those without touch screens will find Windows 10 comfortable.

I’m so impressed with it I’ve installed it on my HP Touchsmart as well (which had Windows 8.1).  After using Windows 10 for an hour I felt so at home with it that Windows 8.1 seems somewhat kludgy now...

I’m excited that I can program both Desktop and Slate applications for a more unified appearance (we’re back to Windows) – particularly since I will be taking advantage of the ability to share source code between them.

I give Windows 10 a vote of 11 (on a scale from 1 to 10).

Universal app / .NET Native encryption/decryption

by billkrat 15. April 2014 19:33

SOURCE CODE: http://PasswordMgr.CodePlex.com change set: 105682

The following TDD demonstrates the value of IOC for building decoupled composite applications.  The logger, encryption provider, and login implementation are registered in the initialize method - emulating how they will be initialized during application start.   

    [TestInitialize]
    public void Initialize()
    {
      _container
        .Register<ILogger, DebugLogger>()
        .Register<IEncryptionProvider, AesEncryption>()
        .Register<ILogin, LoginData>(new LifetimeSingleton());
    }

On lines 37-38 I emulate information that will be pulled from the saved configuration file (set during the password managers application setup).  The application/system login password and salt value (also input by user) will be used to encrypt the data (read more on encryption using salt cryptography).

The concept is that only the device will hold the system login and password with the data being stored in an Azure table, this way if the online table is ever compromised they will be unable to decrypt passwords without the system password and salt values. My initial thoughts are to store them in the roaming location so that all devices will be able to work with the Azure data.   Initially data will be stored on the device – storage on the internet for multi-device support will be optional.

The objective of the framework is to abstract the complexity into base classes so that we can quickly standup new applications, i.e., the actual encryption and decryption of data is accomplished in the GenericBase baseclass, all the UserData class has to do is identify which fields to encrypt, currently this is done by line 116 in the left pane.  Later, when attributes are supported I will use the [Encrypt] attribute which is in place for future support (line 57 left pane).

Note on lines 53 (right pane) and 108 (left pane) that I pass in a password in clear text, however since it is marked as encrypted the value won’t be stored in clear text (reference debug window at bottom of image).   This data is ready to be sent to a data access layer for saving.  When the user wants to see the password (the main purpose of the password manager program) we will use the GetDecrypted<T>() method on line 66 (right pane).

UnitTest

This is made possible because of the login singleton on line 46 (right pane above), I resolve the singleton and set it with the system login and salt value (one time).   Now anytime it is used any class only has to request it from the IOC container as shown below (highlighted).

Baseclass

Note: the GenericBase.Set() method invokes the PropertyChanged event (line 163) so that if XAML controls are bound to the properties the view will be updated accordingly, as with encryption/decryption, this is built-in functionality.

I use the encryption/decryption methods provided on the following link:

http://social.msdn.microsoft.com/Forums/windowsapps/en-US/df082434-08e6-4d16-96b5-ed81639b4eee/how-can-i-generate-the-exact-same-ciphertext-in-winrt-as-this-windows-phone-encryption-code-using?forum=winappswithcsharp

Event Aggregator for Universal App / .NET Native

by billkrat 13. April 2014 05:48

Event Aggregator

Source Code: http://PasswordMgr.CodePlex.com Change set: 105657

Building an IOC Container For Universal Apps/.Net Native was only half the battle in the quest to create a framework that will support decoupled composite applications in this new environment, I also require an event aggregator so that my presenters and view models won’t have to have any knowledge of each other (or any other component); they simple subscribe to available events and when one is raised will respond to it.

Fortunately Prism has a nice event aggregator which I was able to port into my PasswordManager.Shared project (with minor refactoring).  So that I could perform TDD on this project I used linked files (discussed in THIS blog).  This allowed me to create my EventAggregatorFixture and its CanUseEventAggregatorForEvents test method (line 64 of image below).

For the unit test I have the following MockEventClass – the method we are concerned with for this blog is
RaiseEvent()

public class MockEventClass : IBuildup
{
  [SettingInjection]
  public IEventAggregator EventAggregator { get; set; }

  [SettingInjection]
  public ILogger Logger { get; set; }   // not tightly coupled to DebugLogger (can be easily swapped out)

  public void RaiseEvent()
  { 
    EventAggregator.GetEvent<MockEvent>().Publish(new MockEventArgs
    {
      Data = "MockEventClass Raised Event",
      EventType = EventType.MockEvent
    });
  } 

  public void Buildup(IIocContainer container)
  {
    EventAggregator = container.Resolve<IEventAggregator>();
    Logger = container.Resolve<ILogger>();
  }
}

Below on line 74 of the image below we subscribe to the MockEvent:

public class MockEvent : CompositePresentationEvent<MockEventArgs>
{
}

As you can see this is a basic class that provides not only a unique signature for this event but also the event arguments that it will be expecting.  So on line 74 when we receive “e” we know it will be of type MockEventArgs which follows:

public enum EventType { LoggerEvent, MockEvent}

public class MockEventArgs : EventArgs
{
  public string Data { get; set; }

  public EventType EventType { get; set; }
}

This is a significant feature of decoupled communications, we don’t have to have any knowledge of the MockEventClass (the publisher) and it doesn’t have to have knowledge of any subscribers – both publisher and subscriber need only know about the MockEventArgs which can remain in a project common to subscriber/publisher components.   As you can see it will be a simple matter to create new events and their respective EventArgs to ensure we can maintain a clear separation of concerns.

Below we exercise the subscription and publishing capabilities of our event aggregator, we even subscribe to our Logger’s LoggerEvent so that we can bubble the event using the event aggregator.  Note that framework is not tightly coupled to the DebugLogger (registered on line 54) as the framework only knows of ILogger – when an instance is required, as is the case with the MockEventClass above we provide one via the IBuildup implementation.

    public void Buildup(IIocContainer container)
    {
      EventAggregator = container.Resolve<IEventAggregator>();
      Logger = container.Resolve<ILogger>(); 
    }

UnitTest

TDD for universal projects / building an IOC Container for .Net Native

by BillKrat 11. April 2014 03:36

Inversion Of Control

Source Code: http://PasswordMgr.CodePlex.com Changeset: 105644

The new universal project is an odd beast (at this stage of agile development), you can’t build it (grayed out), add references to it, or access it from any of the available unit test. It seems it can only be referenced by the Windows and Phone application associated with it. If you attempt to view the project properties you’ll find it has none (reference image below).

OddBeast
Figure 1

So how do you perform TDD and work with this new project in a manner that is familiar to you?  Linked files, a technique used for multi-targeting development.  Linked files basically means that only one project actually holds any files, the other projects link to the files but doesn’t actually contain a copy of them.

To set things up we have configured our PasswordManager.Windows application to be a .NET Native application with the notion that “if it compiles, it will run”, it is represented by the use case on the right (figure 2), it references the PasswordManager.Shared (universal) project as does the PasswordManager.Phone

I then added my “development environment” which consist of a PasswordManager application (left use case of figure 2) which references  Library.Data and Library.Common projects (both being the project template “Class Library (portable for universal apps)”.   For all practical purposes for this stage of development (TDD) I’ll only be working on the left use cases – the right merely serves as a container for the source code – and if it compiles, it will run.

ProjectReferences
Figure 2

With my projects in place it is now time for me to link the files.  Ideally, I would have liked the originals to be in the Library.Common project as this is the reusable component, however at this stage of what is available I was glad that I could use the linking feature – but the master files have to reside in the universal project as the “Add As Link” feature is only available from the Library.Common (Portable) project (reference figure 4).  

Note in figure 3 below that only the PasswordManager.Shared projects have physical files, the Library Common “links” to the actual files which is represented by a different Icon.

LinkedFiles
Figure 3

Adding a linked file is very easy, from the Library.Common (Portable) project I simply indicated that I wanted to add an existing item.  I navigated to the PasswordManager.Shared folder and selected all of the files and instead of clicking “Add” clicked the down arrow (reference figure 4) and selected “Add As Link”.  Once I can see the “linked” file in my Library.Common (Portable) project I change the namespace so that it appears to be the owner.

LinkedFIle
Figure 4  

Now I can create the Unit Test (ContainerFixture in Library.Common.Tests) and reference the Library.Common (Portable) project which will permit me to perform TDD on the files which actually reside in the universal project.   I can completely ignore the universal project for the entire process, except for when I have to add new files.

All I have to ensure is that I *create* the file in the universal project and then link from it from my Library.Common (Portable project) – a two step process however it pays for itself in development experience. 

Below figure 5 I’ll show the source code for the unit test, I want to take a moment to discuss my agile approach to supporting a feature that does not exist yet in universal applications – attributes.   Ideally, I’d like to set an attribute on my properties that need to be injected, i.e., ILogger on line 9 of figure 5 below so that the container can query for this attribute and inject the applicable implementation instance for that interface.  However, since it is not yet supported I will use an IBuildup interface and each component will have the responsibility of building up itself (minor compromise).

Later, when it is supported I simply have to go into my container and add the new code (lines 95-99 explain below) and pull out the IBuildup interface code.  Now my [SetterInjection] attribute is being used and the Buildup() method become technical debt that can be cleaned out at a later point (as practical).

TechnicalDebt
Figure 5

TDD for my IOC container reveals that I have basic functionality to start development with – next stop, logging.

image 
Figure 6

Simple Mock Class used for TDD:

using Library.Common.Container;
using Library.Common.Logger;

namespace LIbrary.Common.Tests.Mocks
{
  public class SimpleIocMock : IBuildup
  {
    [SettingInjection]
    public ILogger Logger { get; set; }

    public string Data { get; set; }

    // Work-around until Setter / Constructor injection
    // features available in .NET Native
    public void Buildup(IIocContainer container)
    {
      Logger = container.Resolve<ILogger>();
    }
  }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
using Library.Common.Container;
using Library.Common.Logger;
using LIbrary.Common.Tests.Mocks;

namespace LIbrary.Common.Tests
{
  [TestClass]
  public class ContainerFixture
  {
    private const string MockTemplate = "Hello {0}";
    private const string MockParameter = "World!";
    private const string MockExpected = "Hello World!";

    private IIocContainer _container;
    [TestInitialize]
    public void Initialize()
    {
      _container = new IocContainer();
    }

    [TestMethod]
    public void CanBuildupType()
    {
      // Register ILogger with container since SimpleIocMock has
      // a dependency on it
      _container.Register<ILogger, DebugLogger>();

      // *new* up a SimpleIocMock instance
      var mock = new SimpleIocMock();
      
      Assert.IsNull(mock.Logger, "Logger should have been null");

      // Build up the instance
      _container.Buildup(mock);   

      // Mock Logger should be available now
      AssertMockIsValid(mock);    
    }

    [TestMethod]
    public void CanRegisterAndResolve()
    {
      // Register ILogger in container
      _container.Register<ILogger, DebugLogger>();

      // Resolve logger and ensure we have access to DebugLogger
      var logger = _container.Resolve<ILogger>();
      
      // Logger will return what was sent to logger
      var loggerResults = logger.Log(MockTemplate, MockParameter);
      Assert.AreEqual(MockExpected, loggerResults);
    }

    [TestMethod]
    public void DefaultRegistrationIsNewInstance()
    {
      // Register ILogger in container
      _container.Register<ILogger, DebugLogger>();

      // Resolve ILogger twice
      var logger1 = _container.Resolve<ILogger>();
      var logger2 = _container.Resolve<ILogger>();

      // Default behavior is that a new instance will be provided each time
      Assert.AreNotEqual(logger1.Id, logger2.Id);
    }

    [TestMethod]
    public void SingletonRegistrationReturnsSameInstance()
    {
      // Register ILogger in container as singleton
      _container.Register<ILogger, DebugLogger>(new LifetimeSingleton());

      // Resolve ILogger twice
      var logger1 = _container.Resolve<ILogger>();
      var logger2 = _container.Resolve<ILogger>();

      // Both results should be the same DebugLogger instance
      Assert.AreEqual(logger1.Id, logger2.Id);
    }
    
    [TestMethod]
    public void CanRegisterInstance()
    {
      // *new* up a SimpleIocMock instance
      var temp = new SimpleIocMock();
      temp.Data = "My Mock Data";
      
      // Register it with the container
      _container.RegisterInstance<SimpleIocMock>(temp);

      Assert.IsNull(temp.Logger, "Logger should be null at this point");

      // SimpleIocMock has dependency on ILogger - register before resolving
      _container.Register<ILogger, DebugLogger>();

      // Resolve the SimpleIocMock which has a dependency on ILogger
      var mock = _container.Resolve<SimpleIocMock>();

      Assert.IsNotNull(temp.Logger, "Logger should have been resolved as well");
      Assert.AreEqual("My Mock Data", mock.Data);

      AssertMockIsValid(mock);
    }
    
    [TestMethod]
    public void CanResolveAndBuildupClasses()
    {
      // Register ILogger with container since we're going to
      // resolve SimpleIocMock which has a dependency on it
      _container.Register<ILogger, DebugLogger>();

      // Resolve the *class* (versus interface)
      var mock = _container.Resolve<SimpleIocMock>();

      AssertMockIsValid(mock);
    }
    
    [TestMethod]
    public void CanResolveType()
    {
      // Resolve the DebugLogger class
      var logger = _container.Resolve<DebugLogger>();
      
      // Ensure it is not null
      Assert.IsNotNull(logger);
    }
    
    private void AssertMockIsValid(SimpleIocMock mock)
    {
      // First ensure logger is not null
      Assert.IsNotNull(mock.Logger);

      // Send template and parameter to logger
      var loggerResults = mock.Logger.Log(MockTemplate, MockParameter);

      // Ensure return results are not null and expected results
      Assert.IsNotNull(loggerResults);
      Assert.AreEqual(MockExpected, loggerResults);
    }
  }
}

OpenXml Excel Export - Calculating Column width (autofit)

by billkrat 10. April 2014 13:24

Its highly likely that if you are searching for how to calculate the column width for Excel, to create autofit functionality (which currently has to be done manually), then you’ve seen the formula below:

Truncate([{Number of Characters} * {Maximum Digit Width} + {5 pixel padding}] / {Maximum Digit Width} * 256) / 256

Seems like most folks create a blog on the topic, paste this formula in it, and then make a comment like “I don’t know how it works”.  
Which is probably true – because it doesn’t…

Fortunately the following blog takes it a step further and provides some sample code for generating values based on the formula at => http://polymathprogrammer.com/2010/01/18/calculating-column-widths-in-excel-open-xml/.  This was instrumental in helping me find what did work (after a few hours of work and some minor refactoring)…. 

Plug’n play results follow:

private const double digitWidth = 20;
private double GetColumnWidth(string text)
{
    return Math.Truncate((text.Length * (digitWidth + 5.0)) / digitWidth * 200) / 256;
}

I found the formula was missing parenthesis around the (digiWidth + 5.0) which made a big difference in the results. However, even after the fix I found that some Excel columns were wider than they needed to be while others were truncating visible text still.  I made an additional change of 256 to 200 (highlighted in red above) and I got satisfactory results; if you plug in the above code you’ll be able to bypass a lot of headache.  I (like the others) don’t know how it works but sometimes the juice is not worth the squeeze, so I’ll except the satisfactory results and save the brain-strain for the next adventure.

See output window of LinqPad below to see why I went with a digitWidth of 20.
image

LINQPAD source follows:

void Main(){
    double SimpleWidthStr = 0.0f; // graphic measure of text
    double SimpleWidth = 0.0f;
    double WidthOfZero = 0.0f;
    double DigitWidth = 0.0f;
    double MaxDigitWidth = 0.0f;
    double TextWidth = 0.0f;
    string text = "Iced Lemon Tea Is An Awesome Drink!";

    // I just need a Graphics object. Any reasonable bitmap size will do.
    var drawfont = new System.Drawing.Font("Calibri", 11);
    
    using(var g = Graphics.FromImage(new Bitmap(200,200)))
    {
        WidthOfZero = (double)g.MeasureString("Z", drawfont).Width;
        SimpleWidthStr = (double)g.MeasureString(text, drawfont).Width;
        SimpleWidth = SimpleWidthStr / WidthOfZero;
    
        for (int i = (char)'A'; i < 'Z'; ++i)
        {
            DigitWidth = (double)g.MeasureString(i.ToString(), drawfont).Width;
            if (DigitWidth > MaxDigitWidth)
                MaxDigitWidth = DigitWidth;
        }
    }
    
    // Truncate([{Number of Characters} * {Maximum Digit Width} + {5 pixel padding}] / {Maximum Digit Width} * 256) / 256
    TextWidth = Math.Truncate((text.Length * (MaxDigitWidth + 5.0)) / MaxDigitWidth * 256.0) / 256.0;
    string.Format("\t SimpleWidth \t{0} (text={1})\r\n\t"+
                  "WidthOfZero \t{2}\r\n\t\t "+
                  "DigitWidth \t{3}\r\n"+
                  "MaxDigitWidth \t{4}\r\n\t\t "+
                  "TextWidth \t{5}", 
                    SimpleWidth, SimpleWidthStr, 
                    WidthOfZero, 
                    DigitWidth, 
                    MaxDigitWidth, 
                    TextWidth).Dump("Results");

    string.Format("(Simple formula) TextWidth {0}", GetColumnWidth(text)).Dump("Simple Calc");    
}

private const double digitWidth = 20;
private double GetColumnWidth(string text)
{
    return Math.Truncate((text.Length * (digitWidth + 5.0)) / digitWidth * 200) / 256;
}